Потоковое видео не работает на Google TV в приложении Android в версии 3.1 - PullRequest
1 голос
/ 10 января 2012

Я новичок в разработке для Android, и меня попросили создать приложение для Android для Google TV, которое будет показывать пользователю несколько прямых каналов и воспроизводить прямой эфир, когда пользователь выберет один.Мне удалось это сделать, и он работает нормально.Я использовал MediaPlayer для воспроизведения своих потоков, а каналы воспроизводятся должным образом БОЛЬШЕ времени.

Я переопределил setOnErrorListener , чтобы знать, если что-то не так.Это отлавливает большинство ошибок, если таковые имеются, и я finish () активность игрока после отображения правильного сообщения.

Изначально я показываю загрузка сообщение в индикатор выполнения, чтобыпользователь, пока поток готовится.i dismiss () индикатор выполнения и start () MediaPlayer после вызова setOnPreparedListener .

Я не могу запустить rtsp:// поток.после небольшой игры он зависает.

  1. индикатор выполнения остается там, а приложение застряло.
  2. Нажатие кнопки Назад на D-Pad также не работает
  3. Я не получаю ошибок в setOnErrorListener слушателе вообще
  4. Я не могу закрыть приложение, так как всякий раз, когда я нажимаю на значок моего приложения, оно открывает ту же самую черную страницу проигрывателя «Загрузка».

Android 3.1 (API 12) и все URL-адреса потоковначать с rtsp: //

Ниже приведен код файла xml / java:

ПРИМЕЧАНИЕ. Я скопировал и изменил файлы VideoPlayer.java & video_player.xml Пример MediaPlayer_Demo .

video_player.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#000000">

    <SurfaceView android:id="@+id/surface"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </SurfaceView>
</LinearLayout>

Ошибочный VideoPlayer.Java выглядит следующим образом:

public class VideoPlayer extends Activity implements OnBufferingUpdateListener,
    OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener,
    SurfaceHolder.Callback, OnErrorListener {

private static final String TAG = "MediaPlayerDemo";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private Bundle extras;
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
ProgressDialog progressDialog;

/**
 * 
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.video_player);

    this.extras = getIntent().getExtras();

    mPreview = (SurfaceView) findViewById(R.id.surface);
    holder = mPreview.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}

private void playVideo() {
    doCleanUp();
    try {

        this.progressDialog = ProgressDialog.show(this, "", "Loading...",
                true);

        // Check Internet Status
        if (!AppStatus.isInternetAvailable(this)) {
            showErrorToUser(getResources().getText(R.string.about_net)
                    .toString(),
                    "Internet connection is not available or Wi-Fi is not enabled.");
        } else {
            // Create a new media player and set the listeners
            String videoStreamUrl = extras.getString("streamUrl");

            if (videoStreamUrl != null) {
                mMediaPlayer = new MediaPlayer();
                mMediaPlayer.setDataSource(videoStreamUrl);
                mMediaPlayer.setDisplay(holder);
                mMediaPlayer.setOnBufferingUpdateListener(this);
                mMediaPlayer.setOnCompletionListener(this);
                mMediaPlayer.setOnPreparedListener(this);
                mMediaPlayer.setOnVideoSizeChangedListener(this);
                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mMediaPlayer.setOnErrorListener(this);
                mMediaPlayer.prepareAsync();
            }
            else
            {
                showErrorToUser("Invalid Stream URI",
                        "The Video's URI is not valid. Please provide correct URI.");
            }
        }
    } catch (Exception e) {
        Log.e(TAG, "error: " + e.getMessage(), e);
        errorOccured();
    }
}

public void onBufferingUpdate(MediaPlayer arg0, int percent) {
    Log.d(TAG, "onBufferingUpdate percent:" + percent);

}

public void onCompletion(MediaPlayer arg0) {
    Log.d(TAG, "onCompletion called");
}

public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
    Log.v(TAG, "onVideoSizeChanged called");
    if (width == 0 || height == 0) {
        Log.e(TAG, "invalid video width(" + width + ") or height(" + height
                + ")");
        return;
    }
    mIsVideoSizeKnown = true;
    mVideoWidth = width;
    mVideoHeight = height;
    if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
        startVideoPlayback();
    }
}

public void onPrepared(MediaPlayer mediaplayer) {
    Log.d(TAG, "onPrepared called");
    mIsVideoReadyToBePlayed = true;
    if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
        startVideoPlayback();
    }
}

public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
    Log.d(TAG, "surfaceChanged called");

}

public void surfaceDestroyed(SurfaceHolder surfaceholder) {
    Log.d(TAG, "surfaceDestroyed called");
}

public void surfaceCreated(SurfaceHolder holder) {
    Log.d(TAG, "surfaceCreated called");
    playVideo();
}

@Override
protected void onPause() {
    super.onPause();
    releaseMediaPlayer();
    doCleanUp();
}

@Override
protected void onStop() {
    super.onStop();
    releaseMediaPlayer();
    doCleanUp();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    releaseMediaPlayer();
    doCleanUp();
}

private void releaseMediaPlayer() {
    if (mMediaPlayer != null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}

private void doCleanUp() {
    mVideoWidth = 0;
    mVideoHeight = 0;
    mIsVideoReadyToBePlayed = false;
    mIsVideoSizeKnown = false;
}

private void startVideoPlayback() {
    Log.v(TAG, "startVideoPlayback");
    holder.setFixedSize(mVideoWidth, mVideoHeight);

    this.progressDialog.dismiss();

    mMediaPlayer.start();
}

public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
    errorOccured();
    return true;
}

private void errorOccured() {
    UserMessage
            .showPopup(
                    this,
                    "Channel not available",
                    "We are sorry for the inconvenience but this channel is not available right now. Please try later.");
}

private void showErrorToUser(String title, String message) {
    // Hide Progress Bar
    this.progressDialog.dismiss();
    releaseMediaPlayer();
    doCleanUp();

    UserMessage.showPopup(this, title, message);
    }
}

Я создал UserMessage & AppStatus классы для быстрой разработки, я изучил их из SO.Эти занятия хороши и, насколько мне известно, не вызывают ошибок.Я предоставляю их просто для того, чтобы поделиться ими и лучше понять VideoPlayer.java .

Эти классы предназначены только для того, чтобы поделиться ими, чтобы их мог использовать любой другой человек:

UserMessage.Java

public class UserMessage {
public static void showPopup(final Activity activity, String title, String message) {

    View view = View.inflate(activity, R.layout.about, null);
    TextView textView = (TextView) view.findViewById(R.id.message);
    textView.setMovementMethod(LinkMovementMethod.getInstance());
    textView.setText(message);
    new AlertDialog.Builder(activity)
            .setTitle(title)
            .setView(view)
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    activity.finish();
                }
            }).show();
    }
}

AppStatus.Java

public class AppStatus {

public static boolean isInternetAvailable(Context context)  {               

    ConnectivityManager mgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = mgr.getActiveNetworkInfo();

    return (netInfo != null && netInfo.isConnected() && netInfo.isAvailable());
    }
}

Любая помощь очень ценится, так как я почти в конце окончания моейприложение.

Спасибо, что читаете и думаете, даже если вы не можете мне ответить.

1 Ответ

0 голосов
/ 27 января 2012

Ответ на вашу проблему заключается в том, что, хотя мы поддерживаем RTSP, это делается программно, а не аппаратно. Когда вам нужно изменить его масштаб, это также делается в программном обеспечении. Когда вы представляете довольно большой размер, такой как у вас, и его нужно масштабировать, он не работает. Придание поведению вашего видения. MP4 - лучшее решение.

...