我是Android开发的新手,我被要求在Android中为Google TV创建一个应用程序,该应用程序将向用户显示一些直播频道,并在用户选择一个时播放直播。我设法这样做,工作正常。我使用 MediaPlayer 来播放我的流,并且频道在大部分时间都正常播放。
我已覆盖 setOnErrorListener 以了解是否有错误。这可以捕获大部分错误(如果有的话)并且在显示正确的消息后我完成()玩家活动。
最初,当流准备就绪时,我会在进度条中向用户显示加载消息。在调用 setOnPreparedListener 侦听器后,我关闭()进度条,开始() MediaPlayer。
我无法运行rtsp:// stream。玩了一会后就挂了。
使用Android 3.1(API 12),所有流网址均以rtsp://
开头以下是xml / java文件的代码:
注意:我复制并修改了VideoPlayer.java& video_player.xml文件MediaPlayer_Demo example。
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>
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 &amp;用于快速开发的 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());
}
}
我非常感谢任何帮助,因为我差不多完成了我的应用程序。
感谢您阅读和思考,即使您无法回答我。
答案 0 :(得分:0)
你的问题的答案是,虽然我们支持RTSP,但它是用软件完成的,而不是硬件。当您需要重新缩放它时,也可以在软件中完成。当你呈现一个相当大的尺寸时,就像它一样,并且它需要缩放,它在运行中。给你看到的行为。 MP4是更好的解决方案。