zoukankan      html  css  js  c++  java
  • Android 使用PLDroidPlayer播放网络视频 依据视频角度自己主动旋转

    近期由于项目需求 。须要播放网络视频 。于是乎 研究了一番 ,说说我遇到的那些坑

    如今市面上有几个比較主流好用的第三方框架

    当然还有非常多别的视频播放框架 由于我仅仅找到这几个= =!

    由于项目比較急,所以我用的比較简单的 PLDroidPlayer

    首先把须要的jar包和jni文件拷到你的项目中
    这个里面有非常多控件。你们能够依据自己的需求来用指定的控件。我用的是PLVideoTextureView

    <com.pili.pldroid.player.widget.PLVideoTextureView
            android:id="@+id/video"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true" />
    ... prompt'''

    然后findviewbyid找到它

    public class PLVideoTextureActivity extends AppCompatActivity {
    
        private MediaController mMediaController;
        private PLVideoTextureView mVideoView;
        private Toast mToast = null;
        private String mVideoPath = null;
        private int mRotation = 0;
        private int mDisplayAspectRatio = PLVideoTextureView.ASPECT_RATIO_FIT_PARENT; //default
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            setContentView(R.layout.activity_pl_video_texture);
            mVideoView = (PLVideoTextureView) findViewById(R.id.VideoView);
    
            View loadingView = findViewById(R.id.LoadingView);
            mVideoView.setBufferingIndicator(loadingView);
    
            mVideoPath = getIntent().getStringExtra("videoPath");
    
            // If you want to fix display orientation such as landscape, you can use the code show as follow
            //
            // if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            //     mVideoView.setPreviewOrientation(0);
            // }
            // else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            //     mVideoView.setPreviewOrientation(270);
            // }
    
            mVideoPath = getIntent().getStringExtra("videoPath");
    
            AVOptions options = new AVOptions();
    
            int isLiveStreaming = getIntent().getIntExtra("liveStreaming", 1);
            // the unit of timeout is ms
            options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
            options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000);
            // Some optimization with buffering mechanism when be set to 1
            options.setInteger(AVOptions.KEY_LIVE_STREAMING, isLiveStreaming);
            if (isLiveStreaming == 1) {
                options.setInteger(AVOptions.KEY_DELAY_OPTIMIZATION, 1);
            }
    
            // 1 -> hw codec enable, 0 -> disable [recommended]
            int codec = getIntent().getIntExtra("mediaCodec", 0);
            options.setInteger(AVOptions.KEY_MEDIACODEC, codec);
    
            // whether start play automatically after prepared, default value is 1
            options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);
    
            mVideoView.setAVOptions(options);
    
            // You can mirror the display
            // mVideoView.setMirror(true);
    
            // You can also use a custom `MediaController` widget
            mMediaController = new MediaController(this, false, isLiveStreaming == 1);
            mVideoView.setMediaController(mMediaController);
    
            mVideoView.setOnInfoListener(mOnInfoListener);
    //        mVideoView.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
            mVideoView.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
            mVideoView.setOnCompletionListener(mOnCompletionListener);
            mVideoView.setOnSeekCompleteListener(mOnSeekCompleteListener);
            mVideoView.setOnErrorListener(mOnErrorListener);
            mVideoView.setVideoPath(mVideoPath);
            mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT);
            mVideoView.setOnPreparedListener(mOnPreparedListener);
            mVideoView.setOnVideoSizeChangedListener(new PLMediaPlayer.OnVideoSizeChangedListener() {
                @Override
                public void onVideoSizeChanged(PLMediaPlayer plMediaPlayer, int width, int height) {
                    Logger.i("" + width + "---heightL:" + height);
                    if (width > height) {
                        //视频是横屏 旋转方向
                       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    }
    
    
                }
            });
    
            mVideoView.setVideoPath(mVideoPath);
            mVideoView.start();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            mToast = null;
            mVideoView.pause();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            mVideoView.start();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mVideoView.stopPlayback();
        }
    
        public void onClickRotate(View v) {
            mRotation = (mRotation + 90) % 360;
            mVideoView.setDisplayOrientation(mRotation);
        }
    
        public void onClickSwitchScreen(View v) {
            mDisplayAspectRatio = (mDisplayAspectRatio + 1) % 5;
            mVideoView.setDisplayAspectRatio(mDisplayAspectRatio);
            switch (mVideoView.getDisplayAspectRatio()) {
                case PLVideoTextureView.ASPECT_RATIO_ORIGIN:
                    showToastTips("Origin mode");
                    break;
                case PLVideoTextureView.ASPECT_RATIO_FIT_PARENT:
                    showToastTips("Fit parent !");
                    break;
                case PLVideoTextureView.ASPECT_RATIO_PAVED_PARENT:
                    showToastTips("Paved parent !");
                    break;
                case PLVideoTextureView.ASPECT_RATIO_16_9:
                    showToastTips("16 : 9 !");
                    break;
                case PLVideoTextureView.ASPECT_RATIO_4_3:
                    showToastTips("4 : 3 !");
                    break;
                default:
                    break;
            }
        }
    
        private PLMediaPlayer.OnErrorListener mOnErrorListener = new PLMediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(PLMediaPlayer mp, int errorCode) {
                switch (errorCode) {
                    case PLMediaPlayer.ERROR_CODE_INVALID_URI:
                        showToastTips("Invalid URL !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_404_NOT_FOUND:
                        showToastTips("404 resource not found !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_CONNECTION_REFUSED:
                        showToastTips("Connection refused !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_CONNECTION_TIMEOUT:
                        showToastTips("Connection timeout !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_EMPTY_PLAYLIST:
                        showToastTips("Empty playlist !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_STREAM_DISCONNECTED:
                        showToastTips("Stream disconnected !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_IO_ERROR:
                        showToastTips("Network IO Error !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_UNAUTHORIZED:
                        showToastTips("Unauthorized Error !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_PREPARE_TIMEOUT:
                        showToastTips("Prepare timeout !");
                        break;
                    case PLMediaPlayer.ERROR_CODE_READ_FRAME_TIMEOUT:
                        showToastTips("Read frame timeout !");
                        break;
                    case PLMediaPlayer.MEDIA_ERROR_UNKNOWN:
                    default:
                        showToastTips("unknown error !");
                        break;
                }
                // Todo pls handle the error status here, retry or call finish()
                finish();
                // If you want to retry, do like this:
                // mVideoView.setVideoPath(mVideoPath);
                // mVideoView.start();
                // Return true means the error has been handled
                // If return false, then `onCompletion` will be called
                return true;
            }
        };
    
    
         private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(PLMediaPlayer plMediaPlayer) {
    //            finish();
                showToast("视频播放完毕");
            }
        };
    
        private PLMediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new PLMediaPlayer.OnBufferingUpdateListener() {
            @Override
            public void onBufferingUpdate(PLMediaPlayer plMediaPlayer, int precent) {
            }
        };
    
        private PLMediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new PLMediaPlayer.OnSeekCompleteListener() {
            @Override
            public void onSeekComplete(PLMediaPlayer plMediaPlayer) {
                Logger.d("onSeekComplete !");
            }
    
        };
    
        private PLMediaPlayer.OnPreparedListener mOnPreparedListener = new PLMediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(PLMediaPlayer plMediaPlayer) {
    
    
            }
        };
        private PLMediaPlayer.OnInfoListener mOnInfoListener = new PLMediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(PLMediaPlayer plMediaPlayer, int what, int extra) {
                switch (what) {
                    case PLMediaPlayer.MEDIA_INFO_BUFFERING_START:
                        Logger.i("正在缓冲----");
                        //開始缓存,暂停播放
                        if (isPlaying()) {
    //                        stopPlayer();
                            if (mVideoView != null) {
                                mVideoView.pause();
                            }
                            needResume = true;
                        }
                        rl_loading.setVisibility(View.VISIBLE);
                        break;
                    case PLMediaPlayer.MEDIA_INFO_BUFFERING_END:
                    case PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                        Logger.i("缓冲完毕----");
                        //缓存完毕,继续播放
                        if (needResume)
    //                        startPlayer();
                            if (mVideoView != null) {
                                mVideoView.start();
                            }
                        rl_loading.setVisibility(View.GONE);
                        break;
                    case PLMediaPlayer.MEDIA_INFO_BUFFERING_BYTES_UPDATE:
                        //显示 下载速度
                        Logger.e("download rate:" + extra);
                        //mListener.onDownloadRateChanged(arg2);
                        break;
                }
                Logger.i("onInfo:" + what + "___" + extra);
                return false;
            }
        };
    }

    这样就完毕了普通视频的播放和旋转视频播放

    看似简单 事实上隐藏着大问题 。也就是我所说的大坑
    如今我是这样推断角度的 当视频的宽度大于高度的 我就觉得这是一个横屏的视频 ,也就是说假如这个视频是1330X720(我随便说的尺寸,仅仅为举例)如今宽度大于高度了 那么这就是一个横屏的视频,可是我仅仅要播放手机拍摄的视频就会发现视频被放大了 ,可是事实上我录制视频的时候是竖着排的 。可视播放的时候却给我横着过来了,然后我就去看这个手机拍摄视频的尺寸 如今一般录制视频最低都是1280X720 。恰好符合我推断的逻辑 。难道他真是横着的? 然后我就用系统自带的播放器打开 ,竟然没有横过来 ,而是竖着播放的 ,可它是怎么知道这个方向呢?于是我在百度搜 。确实能够获取到本地视频的角度。可是好像低版本号好像不兼容,然后依据角度去推断 是否须要旋转。可是我这个是网络视频啊 ,网络视频怎么获取到视频角度啊 ? 我第一反应是 上传视频的时候把宽高角度传到server ,然后获取的时候依据这个角度旋转 ,可是别人播放网络视频的时候也没有传角度过去啊 - - 然后我就在github上面问那个作者 ,结果他说

    “onInfo: 10001, 90”, 收到这个消息后。使用 PLVideoTextureView 的 setDisplayOrientation 旋转显示的方向。后面会补充这个回调的接口和文档。

    我晕 ,你这不说 谁知道啊 坑死啊 - -
    然后我就改动了下代码

     /**
         * 视频的方向
         */
    private int mVideoRotation;
        private boolean needResume;
        private PLMediaPlayer.OnInfoListener mOnInfoListener = new PLMediaPlayer.OnInfoListener() {
            @Override
            public boolean onInfo(PLMediaPlayer plMediaPlayer, int what, int extra) {
                switch (what) {
                    case PLMediaPlayer.MEDIA_INFO_BUFFERING_START:
                        Logger.i("正在缓冲----");
                        //開始缓存,暂停播放
                        if (isPlaying()) {
    //                        stopPlayer();
                            if (mVideoView != null) {
                                mVideoView.pause();
                            }
                            needResume = true;
                        }
                        rl_loading.setVisibility(View.VISIBLE);
                        break;
                    case PLMediaPlayer.MEDIA_INFO_BUFFERING_END:
                    case PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                        Logger.i("缓冲完毕----");
                        //缓存完毕。继续播放
                        if (needResume)
    //                        startPlayer();
                            if (mVideoView != null) {
                                mVideoView.start();
                            }
                        rl_loading.setVisibility(View.GONE);
                        break;
                    case PLMediaPlayer.MEDIA_INFO_BUFFERING_BYTES_UPDATE:
                        //显示 下载速度
                        Logger.e("download rate:" + extra);
                        //mListener.onDownloadRateChanged(arg2);
                        break;
                    case 10001:
                        //保存视频角度
                        mVideoRotation=extra;
    
                        break;
                }
                Logger.i("onInfo:" + what + "___" + extra);
                return false;
            }
        };

    然后在onVideoSizeChanged的回调里这样

     mVideoView.setOnVideoSizeChangedListener(new PLMediaPlayer.OnVideoSizeChangedListener() {
                @Override
                public void onVideoSizeChanged(PLMediaPlayer plMediaPlayer, int width, int height) {
                    Logger.i("" + width + "---heightL:" + height);
                    if (width > height&&mVideoRotation==0) {
                        //旋转方向
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    }
                    //假设视频角度是90度
                    if(mVideoRotation==90)
                    {
                       //旋转视频
                        mVideoView.setDisplayOrientation(270);
                    }
    
                }
            });

    这样 无论是什么视频 播放最终正常了 - -

    转载请注明出处 http://www.weyye.me/detail/Android-PLDroidPlayer%E6%92%AD%E6%94%BE/

  • 相关阅读:
    POJ 1659 Frogs' Neighborhood
    zoj 2913 Bus Pass(BFS)
    ZOJ 1008 Gnome Tetravex(DFS)
    POJ 1562 Oil Deposits (DFS)
    zoj 2165 Red and Black (DFs)poj 1979
    hdu 3954 Level up
    sgu 249 Matrix
    hdu 4417 Super Mario
    SPOJ (BNUOJ) LCM Sum
    hdu 2665 Kth number 划分树
  • 原文地址:https://www.cnblogs.com/llguanli/p/8733945.html
Copyright © 2011-2022 走看看