基于七牛播放器的直播
来源:互联网 发布:龙泉驾校网络上课流程 编辑:程序博客网 时间:2024/05/18 02:20
这个播放器是用的七牛的播放器,直播一般都是需要后台先推流,然后根据后台给的播放地址开始直播,我这里只是一个演示,自己在网上找了一个地址,可以直接播放。
1. 拷贝架包和so文件
复制pldroid-player-1.5.0.jar到libs目录以及复制相关so文件到libs目录下面,build.gradle文件里面添加,用于编译.so文件
sourceSets{ main(){ jniLibs.srcDirs=['libs'] } }
2. 布局中使用
<com.pili.pldroid.player.widget.PLVideoView android:id="@+id/id_video_view" android:layout_width="match_parent" android:layout_height="match_parent" />
3. 代码中使用
代码比较简单 直接拷贝全部代码了
package com.livevideo.zlc.ui;import android.content.Context;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.media.AudioManager;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.os.PowerManager;import android.support.v4.content.ContextCompat;import android.view.OrientationEventListener;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.TextView;import com.livevideo.zlc.MyApp;import com.livevideo.zlc.R;import com.livevideo.zlc.utils.LogUtil;import com.livevideo.zlc.utils.NetworkStateUtil;import com.livevideo.zlc.utils.ScreenUtil;import com.livevideo.zlc.utils.StatusBarUtil;import com.pili.pldroid.player.AVOptions;import com.pili.pldroid.player.PLMediaPlayer;import com.pili.pldroid.player.widget.PLVideoView;//直播public class LiveActivity extends BaseActivity implements View.OnClickListener{ private ImageView im_zhuan_fangda; private ImageView im_room_video_off; private ImageView im_fanhui2; private TextView id_tv_load; private ImageView id_iv_load; private RelativeLayout id_rl_video; private PLVideoView mVideoView; private LinearLayout id_ll_head; private LinearLayout id_ll_bottom; private LinearLayout id_ll_load; private String TAG = ""; private PowerManager.WakeLock mWakeLock = null; private String mVideoPath = ""; private int mDisplayAspectRatio = PLVideoView.ASPECT_RATIO_16_9; private static final int MESSAGE_ID_RECONNECTING = 0x01; boolean showF = true; private boolean canChanged = true; private boolean isVerticalScreen = true; // 是不是竖屏 private Handler handler = new Handler(Looper.getMainLooper()); private int canReconnect = 1; //1代表可以重新连接 //控制面板的显示与隐藏 final Runnable runnable = new Runnable() { @Override public void run() { LogUtil.e("执行动画",showF+""); if(showF){//隐藏动画 showView(View.GONE,id_ll_head,id_ll_bottom); }else{ //显示动画 showView(View.VISIBLE,id_ll_head,id_ll_bottom); show_or_hidden(3000); } showF = !showF; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_live); setVolumeControlStream(AudioManager.STREAM_MUSIC); PowerManager pm = (PowerManager) this.getSystemService(POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "Test"); TAG = this.getClass().getSimpleName(); initView(); initData(); initListener(); } @Override protected void onStart() { super.onStart(); show_or_hidden(3000); } private void initView(){ im_room_video_off= findView(R.id.id_iv_video_bg); im_zhuan_fangda = findView(R.id.id_im_rotate); mVideoView = findView(R.id.id_video_view); im_fanhui2 = findView(R.id.im_fanhui2); id_tv_load = findView(R.id.id_tv_load); id_iv_load = findView(R.id.id_iv_load); id_rl_video = findView(R.id.id_rl_video); id_ll_head = findView(R.id.id_ll_head); id_ll_bottom = findView(R.id.id_ll_bottom); id_ll_load = findView(R.id.id_ll_load); ViewGroup.LayoutParams params = id_rl_video.getLayoutParams(); int width = params.width = ScreenUtil.getScreenWidth(this); params.height = width*9 / 16 ; id_rl_video.setLayoutParams(params); } private void initListener(){ im_fanhui2.setOnClickListener(this); id_rl_video.setOnClickListener(this); im_zhuan_fangda.setOnClickListener(this); id_tv_load.setOnClickListener(this); } private void initData(){ mVideoPath = "rtmp://live.hkstv.hk.lxdns.com/live/hks"; LogUtil.e("mVideoPath",mVideoPath); initVideo(); } //初始化七牛视频播放器 private void initVideo(){ 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", AVOptions.MEDIA_CODEC_AUTO); //0是软解,1是硬解,2是自动 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); mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_16_9); // Set some listeners mVideoView.setOnInfoListener(mOnInfoListener); // mVideoView.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener); mVideoView.setOnBufferingUpdateListener(mOnBufferingUpdateListener); mVideoView.setOnCompletionListener(mOnCompletionListener); mVideoView.setOnSeekCompleteListener(mOnSeekCompleteListener); mVideoView.setOnErrorListener(mOnErrorListener); mVideoView.setVideoPath(mVideoPath); } //直播相关 protected Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { if (msg.what != MESSAGE_ID_RECONNECTING) { return; } if (!NetworkStateUtil.instance().isNetworkConnected(MyApp.getContext())) { sendReconnectMessage(); return; } mVideoView.setVideoPath(mVideoPath); mVideoView.start(); } }; private PLMediaPlayer.OnInfoListener mOnInfoListener = new PLMediaPlayer.OnInfoListener() { @Override public boolean onInfo(PLMediaPlayer plMediaPlayer, int what, int extra) { LogUtil.e("OnInfoListener","Info"); return false; } }; private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() { @Override public void onCompletion(PLMediaPlayer plMediaPlayer) { LogUtil.e("OnCompletionListener","播放完成"); canReconnect = 1; showView(View.VISIBLE,im_room_video_off,id_ll_load); id_tv_load.setBackgroundResource(R.drawable.shape_btn_main_k_5dp); id_tv_load.setText("重新加载"); } }; private PLMediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new PLMediaPlayer.OnBufferingUpdateListener() { @Override public void onBufferingUpdate(PLMediaPlayer plMediaPlayer, int precent) { LogUtil.e("OnBufferingUpdateListener","在缓冲更新"); canReconnect = 0; im_room_video_off.setVisibility(View.GONE); showView(View.INVISIBLE,id_ll_load); } }; private PLMediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new PLMediaPlayer.OnSeekCompleteListener() { @Override public void onSeekComplete(PLMediaPlayer plMediaPlayer) { canReconnect = 0; LogUtil.e("OnSeekCompleteListener","链接完成"); im_room_video_off.setVisibility(View.GONE); showView(View.INVISIBLE,id_ll_load); } }; private PLMediaPlayer.OnErrorListener mOnErrorListener = new PLMediaPlayer.OnErrorListener() { @Override public boolean onError(PLMediaPlayer plMediaPlayer, int errorCode) { LogUtil.e(TAG, "Error happened, errorCode = " + errorCode); switch (errorCode) { case PLMediaPlayer.ERROR_CODE_INVALID_URI: showToastTips("无效的播放地址 !",true); break; case PLMediaPlayer.ERROR_CODE_404_NOT_FOUND: showToastTips("未找到资源 !",true); break; case PLMediaPlayer.ERROR_CODE_CONNECTION_REFUSED: showToastTips("连接错误",true); break; case PLMediaPlayer.ERROR_CODE_CONNECTION_TIMEOUT: showToastTips("连接超时 !",true); break; case PLMediaPlayer.ERROR_CODE_EMPTY_PLAYLIST: showToastTips("空的播放列表 !",true); break; case PLMediaPlayer.ERROR_CODE_STREAM_DISCONNECTED: showToastTips("断开连接 !",true); break; case PLMediaPlayer.ERROR_CODE_IO_ERROR: showToastTips("网络IO错误 !",true); break; case PLMediaPlayer.ERROR_CODE_UNAUTHORIZED: showToastTips("未经授权的错误 !",true); break; case PLMediaPlayer.ERROR_CODE_PREPARE_TIMEOUT: showToastTips("请求超时 !",true); break; case PLMediaPlayer.ERROR_CODE_READ_FRAME_TIMEOUT: showToastTips("读帧超时 !",false); break; case PLMediaPlayer.MEDIA_ERROR_UNKNOWN: break; default: showToastTips("未知错误 !",true); break; } return true; } }; private void showToastTips(final String tips,boolean isShow) { LogUtil.e("Play==",tips); if(isShow){ canReconnect = 1; showView(View.VISIBLE,im_room_video_off,id_ll_load); id_tv_load.setBackgroundResource(R.drawable.shape_btn_main_k_5dp); id_tv_load.setText("重新加载"); }else{ canReconnect = 0; sendReconnectMessage(); } } private void sendReconnectMessage() { id_ll_load.setVisibility(View.VISIBLE); id_tv_load.setBackgroundColor(ContextCompat.getColor(this,R.color.null_color)); id_tv_load.setText("正在加载..."); mHandler.removeCallbacksAndMessages(null); mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ID_RECONNECTING), 3000); } boolean isFullScreen = false; /** * 当横竖屏切换时执行的一些操作 */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig);LogUtil.e("onConfigurationChanged",newConfig.orientation+""); //全屏看视频 if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { if(StatusBarUtil.hasNavBar(this)) StatusBarUtil.hideBottomUIMenu(this); int matchParent = ViewGroup.LayoutParams.MATCH_PARENT; setVideoContainerParam(matchParent,matchParent); mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_PAVED_PARENT); isFullScreen = true; StatusBarUtil.fullscreen(true,this); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { //从视频全屏界面恢复竖屏 if(StatusBarUtil.hasNavBar(this)) StatusBarUtil.showBottomUiMenu(this); int screenWidth = ScreenUtil.getScreenWidth(this); setVideoContainerParam(screenWidth,screenWidth * 9 / 16); StatusBarUtil.fullscreen(false,this); mVideoView.setDisplayAspectRatio(mDisplayAspectRatio); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); isFullScreen = false; } } private void setVideoContainerParam(int w,int h) { ViewGroup.LayoutParams params = id_rl_video.getLayoutParams(); params.width = w; params.height = h; id_rl_video.setLayoutParams(params); } MyOrientationDetector myOrientationDetector; @Override public void onResume() { super.onResume(); mVideoView.start(); mWakeLock.acquire(); myOrientationDetector = new MyOrientationDetector(this); myOrientationDetector.enable(); } @Override public void onPause() { super.onPause(); mVideoView.pause(); mWakeLock.release(); myOrientationDetector.disable(); } @Override protected void onDestroy() { super.onDestroy(); mVideoView.stopPlayback(); handler.removeCallbacks(runnable); } @Override public void onBackPressed() { if(isFullScreen){ canChanged = false; LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }else{ super.onBackPressed(); } } private void show_or_hidden(int time){ handler.removeCallbacks(runnable); //清理前一个轮询器 handler.postDelayed(runnable,time); } private void showView(int visible,View... views){ for (View v : views) { v.setVisibility(visible); } } @Override public void onClick(View view) { switch (view.getId()){ case R.id.im_fanhui2: if(isFullScreen){ canChanged = false; LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }else{ finish(); } break; case R.id.id_im_rotate: if (isFullScreen) {// 如果当前是横屏,则切换为竖屏 canChanged = false; LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else {// 如果当前是竖屏,则切换为横屏 canChanged = false; LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } isFullScreen = !isFullScreen; break; case R.id.id_tv_load: if(canReconnect==1){ sendReconnectMessage(); } break; case R.id.id_rl_video: show_or_hidden(0); break; } } //自定义加速度传感器的监听事件 public class MyOrientationDetector extends OrientationEventListener { public MyOrientationDetector( Context context ) { super(context ); } @Override public void onOrientationChanged(int orientation) { if(orientation == OrientationEventListener.ORIENTATION_UNKNOWN) { return; //手机平放时,检测不到有效的角度 } //只检测是否有四个角度的改变 if( orientation > 350 || orientation< 10 ) { //0度 isVerticalScreen = true; if(!canChanged){ return; } LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); } else if( orientation > 80 &&orientation < 100 ) { //90度 isVerticalScreen = false; if(!canChanged){ return; } LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } else if( orientation > 170 &&orientation < 190 ) { //180度 isVerticalScreen = true; if(!canChanged){ return; } LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); } else if( orientation > 260 &&orientation < 280 ) { //270度 isVerticalScreen = false; if(!canChanged){ return; } LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } else { } //物理横屏 canChanged = (isFullScreen == !isVerticalScreen); } }}
4. 清单文件中添加权限
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5. 联系方式
qq:1509815887 email : zlc921022@163.com phone : 18684732678
6. 下载地址
点击去下载
阅读全文
0 0
- 基于七牛播放器的直播
- 基于 Vue 的直播播放器实战
- 基于 Vue 的直播播放器实战
- 基于Flash播放器的P2P直播解决方案
- 基于RTMP协议的Flash流媒体网页直播播放器
- 基于Live555,ffmpeg的RTSP播放器直播与点播
- iOS直播-播放基于RTMP协议的视频
- iOS直播-播放基于RTMP协议的视频
- [绍棠] iOS直播-播放基于RTMP协议的视频
- 七牛 直播的延迟与优化
- python 七牛的直播实时截图
- M3U8直播播放器
- ckplayer播放器 直播
- 《视频直播技术详解》系列之七:现代播放器原理
- 《视频直播技术详解》系列之七:现代播放器原理
- 七牛直播demo链接
- 七牛直播服务sdk
- ios直播---基于LFLiveKit的直播项目
- leetcode_java_第一题 two sum
- Flask项目文件目录
- C++处理XML文件
- 惊喜!Mat研究(1)
- 一道画风清奇的数位dp
- 基于七牛播放器的直播
- File Transfer
- Spring FrameWork学习笔记(一)Spring框架综述
- JDBC部分知识点
- 【完全解决】Ubuntu下正确安装VMware Tools及安装搜狗输入法
- 当你老了,一生最后悔什么?大数据告诉你!
- 02-线性结构1 两个有序链表序列的合并
- 求二叉树的深度和宽度[Java]
- 迅雷下载边下边播设置为本地安装的浏览器