我是 Android 开发的新手,我被要求在 Android 中为 Google TV 创建一个应用程序,该应用程序将向用户显示一些直播频道,并在用户选择一个时播放直播。我已经设法做到了,而且工作正常。我使用MediaPlayer播放我的流媒体,而 Channels 大部分时间都可以正常播放。
我已经覆盖了 setOnErrorListener以了解是否有问题。如果有任何错误,这将捕获大部分错误,并且我在显示正确消息后完成()玩家活动。
最初,当流准备就绪时,我在进度条中向用户显示加载消息。在调用setOnPreparedListener侦听器后,我关闭()进度条并启动() MediaPlayer 。
我无法运行 rtsp:// 流。玩了一会儿就挂了。
- 进度条仍然存在,应用程序有点卡住了。
- 按方向键上的返回按钮也不起作用
- 我在setOnErrorListener监听器中没有收到任何错误
- 我无法关闭应用程序,因为每当我单击我的应用程序图标时,它都会打开相同的黑色“正在加载”播放器页面..
使用 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。
这些类如下,仅供分享,以便其他人可以使用它们:
用户消息.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();
}
}
应用状态.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());
}
}
非常感谢任何帮助,因为我快要完成我的应用程序了。
即使您无法回答我,也感谢您的阅读和思考。