博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 使用PLDroidPlayer播放网络视频 依据视频角度自己主动旋转
阅读量:6311 次
发布时间:2019-06-22

本文共 13230 字,大约阅读时间需要 44 分钟。

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

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

  • Vitamio ( 体积比較大,有商业化风险 github:)
  • ijkplayer(B站下开源的框架 体积大 配置环境比較麻烦 github: )
  • PLDroidPlayer(七牛依据ijkplayer二次开发的 定制简单 github:)

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

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

首先把须要的jar包和jni文件拷到你的项目中

这个里面有非常多控件。你们能够依据自己的需求来用指定的控件。我用的是PLVideoTextureView

... 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:" + 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:" + width + "---heightL:" + height);                if (width > height&&mVideoRotation==0) {                    //旋转方向                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);                }                //假设视频角度是90度                if(mVideoRotation==90)                {                   //旋转视频                    mVideoView.setDisplayOrientation(270);                }            }        });

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

转载请注明出处

你可能感兴趣的文章
LINUX下 lamp安装及配置
查看>>
BZOJ3105 [cqoi2013]新Nim游戏
查看>>
困惑的前置操作与后置操作
查看>>
SDNU 1269.整数序列(水题)
查看>>
BZOJ 2118 Dijkstra
查看>>
Go语言基础之结构体
查看>>
SpringCloud:Eureka Client项目搭建(Gradle项目)
查看>>
jqueryValidate
查看>>
ATL使用IE控件,并且屏蔽右键
查看>>
Jenkins
查看>>
linux下使用screen和ping命令对网络质量进行监控
查看>>
数据库设计技巧
查看>>
css定位概述
查看>>
C# 动态修改配置文件 (二)
查看>>
BOM:文档对象模型 --树模型
查看>>
我的Android进阶之旅------>WindowManager.LayoutParams介绍
查看>>
segment
查看>>
获取鼠标的原始移动值
查看>>
Linux信号 编程
查看>>
有关滚动与位置
查看>>