这个播放器是用的七牛的播放器,直播一般都是需要后台先推流,然后根据后台给的播放地址开始直播,我这里只是一个演示,自己在网上找了一个地址,可以直接播放。

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.PLVideoViewandroid: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() {@Overridepublic 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;}};@Overrideprotected 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();}@Overrideprotected 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 msoptions.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 1options.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 1options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);mVideoView.setAVOptions(options);mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_16_9);// Set some listenersmVideoView.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()) {@Overridepublic 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() {@Overridepublic boolean onInfo(PLMediaPlayer plMediaPlayer, int what, int extra) {LogUtil.e("OnInfoListener","Info");return false;}};private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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;/*** 当横竖屏切换时执行的一些操作*/@Overridepublic 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;@Overridepublic void onResume() {super.onResume();mVideoView.start();mWakeLock.acquire();myOrientationDetector = new MyOrientationDetector(this);myOrientationDetector.enable();}@Overridepublic void onPause() {super.onPause();mVideoView.pause();mWakeLock.release();myOrientationDetector.disable();}@Overrideprotected void onDestroy() {super.onDestroy();mVideoView.stopPlayback();handler.removeCallbacks(runnable);}@Overridepublic 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);}}@Overridepublic 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 );}@Overridepublic 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. 下载地址

点击去下载

基于七牛播放器的直播相关推荐

  1. MFC+DuiVision结合VLC播放器开发直播客户端

    MFC+DuiVision结合VLC播放器开发直播客户端 说明:windows 10 VS2015社区版 关键字:c++ VisualStudio DuiVision VLC播放器 开发这个视频播放器 ...

  2. iOS软件开发 - 基于ijkPlayer的播放器框架

    基于ijkPlayer的播放器,支持网络视频.RTMP直播.视频转播等 3分钟快速集成播放器,支持小屏.全屏模式 分享之前我还是要推荐下我自己建的iOS开发学习群:680565220,群里都是学ios ...

  3. 安卓实训项目:基于储存卡音乐播放器实训报告5.0

    安卓实训项目:基于储存卡音乐播放器实训报告5.0 (一)功能要求 在基于存储卡音乐播放器V0.4基础上,作如下修改: 1.创建应用程序常量接口保存广播频道常量 2.在音乐播放器应用程序类里添加两个属性 ...

  4. 安卓实训项目:基于储存卡音乐播放器实训报告4.0

    功能要求 在基于存储卡音乐播放器V0.3基础上,作如下修改: 1.创建方法能扫描存储卡上所有mp3文件(采用递归算法) ----完成 2.用自定义应用程序类存放全局数据和方法 ----完成 3.利用异 ...

  5. 安卓第一阶段实训项目:基于存储卡音乐播放器(更新中……)

    文章目录 一.项目功能要求 二.涉及知识点 三.实现思路 1.基于存储卡音乐播放器V0.1 2.基于存储卡音乐播放器V0.2 3.基于存储卡音乐播放器V0.3 4.基于存储卡音乐播放器V0.4 5.基 ...

  6. 一个简单的基于 DirectShow 的播放器 2(对话框类)

    上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器  1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...

  7. 一个简单的基于 DirectShow 的播放器 1(封装类)

    DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...

  8. 基于android音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目<---基于android音乐播放器的设计----------->是本人在指导教师的指导下,进行研究工作所取得的成 ...

  9. android音乐播放器ppt,基于Android音乐播放器设计与开发.ppt

    基于Android音乐播放器设计与开发 毕业设计 基于Android的音乐播放器 设计与开发 设计概述 研究背景 研究意义 研究目标 系统演示 研究背景 随着Android智能手机的普及,用户越来越能 ...

  10. 基于android的音乐播放器毕业设计,基于android音乐播放器的毕业设计ppt

    <基于android音乐播放器的毕业设计ppt>由会员分享,可在线阅读,更多相关<基于android音乐播放器的毕业设计ppt(29页珍藏版)>请在人人文库网上搜索. 1.1. ...

最新文章

  1. python打开网页存图_python 获取网页图片 保存在本地
  2. TCP/IP反码求和校验
  3. 【转】在CSS中 ID与Class的区别?谢谢
  4. sublime中文输入(转)
  5. window部署python项目_Django在Window下的部署
  6. springboot md5加密_实在!基于Springboot和WebScoket,写了一个在线聊天小程序
  7. 3月第一周中国五大顶级域名增6万 美国增1.8万
  8. php5.5.35安装,如何安装php5
  9. “Head First 设计模式“ :策略模式
  10. 关于Dijkstra三种堆速度的研究
  11. 【推荐系统】智能推荐算法在直播场景中的应用
  12. 22考研清华电子系957,390+高分上岸初复试经验分享
  13. c语言错误 应输入声明,C++错误:应输入声明
  14. OT安全|工业控制系统(ICS)六大安全实践
  15. 安卓开发上传相册图片成功上传拍照图片失败解决办法
  16. 人生于世上有几个知己,多少友谊能长存
  17. (一)unity自带的着色器源码剖析之——————UnityShaderVariables.cginc文件
  18. 假期读书计划表怎么写?能够随时查看读书计划的手机便签
  19. Android利用贝塞尔曲线实现翻书效果(适配AndroidX)
  20. Java窗体边框颜色_【转】窗口效果,带边框、不带边框、设定窗口边框颜色

热门文章

  1. 使用Python读取和播放音频文件
  2. DenseNet详解
  3. 计算机组成原理考研笔记
  4. java项目怎么启动_github上的java项目怎么运行(面向小白)
  5. 一级计算机25套上网,全国计算机等级考试一级试题(25套)[1]
  6. php \n不能换行
  7. 电脑 Google浏览器 截长屏 无任何辅助软件
  8. 北航计算机组成原理课程设计-2020秋 PreProject-Logisim-Logisim组合逻辑电路
  9. 一种数字全息自动聚焦技术研究及实例分析
  10. java语句以什么结尾_[JAVA] 关于语句的结尾