视频流不适用于3.1版Android应用中的Google TV

时间:2012-01-10 10:14:23

标签: android eclipse google-tv

我是Android开发的新手,我被要求在Android中为Google TV创建一个应用程序,该应用程序将向用户显示一些直播频道,并在用户选择一个时播放直播。我设法这样做,工作正常。我使用 MediaPlayer 来播放我的流,并且频道在大部分时间都正常播放。

我已覆盖 setOnErrorListener 以了解是否有错误。这可以捕获大部分错误(如果有的话)并且在显示正确的消息后我完成()玩家活动。

最初,当流准备就绪时,我会在进度条中向用户显示加载消息。在调用 setOnPreparedListener 侦听器后,我关闭()进度条,开始() MediaPlayer。

我无法运行rtsp:// stream。玩了一会后就挂了。

  1. 进度条仍在那里,应用程序有点卡住了。
  2. 按D-Pad上的后退按钮不起作用
  3. 我在 setOnErrorListener 监听器中没有收到任何错误
  4. 我无法关闭应用程序,因为每当我点击我的应用程序图标时,它都会打开相同的黑色“正在加载”播放器页面..
  5. 使用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>
    

    错误的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 &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());
        }
    }
    

    我非常感谢任何帮助,因为我差不多完成了我的应用程序。

    感谢您阅读和思考,即使您无法回答我。

1 个答案:

答案 0 :(得分:0)

你的问题的答案是,虽然我们支持RTSP,但它是用软件完成的,而不是硬件。当您需要重新缩放它时,也可以在软件中完成。当你呈现一个相当大的尺寸时,就像它一样,并且它需要缩放,它在运行中。给你看到的行为。 MP4是更好的解决方案。