教你用三种方式打造一款简单的网络播放器

1-前言

   视频类、直播类APP最近几年一直都比较火爆,占据下载排行榜的前列。华为视频服务提供视频播放服务,助力开发者快速构建视频特性,帮助开发者向用户提供视频媒体体验。
   本文介绍了几种简单实现网络视频播放器的方式,包括使用Android原生的,使用第三方SDK,以及使用华为视频服务三种方式,以及之间的差异。

2-网络播放器实现的方案

完成视频播放有如下几种方案

  1. VideoView,Android为开发人员封装好的简单的播放视频媒体的方式,提供了一些基本方法(时间轴,进度条等)

  2. SurfaceView +MediaPlayer, SurfaceView用于展示,MediaPlayer用于媒体文件播放的组件。

  3. 专业的视频公司,一般自定义自己的流媒体库,完成视频网站和直播的相关工作,比如Ijkplayer 是Bilibili发布的基于 FFplay 的轻量级 Android/iOS 视频播放器。实现了跨平台功能,API 易于集成;编译配置可裁剪,方便控制安装包大小;支持硬件加速解码,更加省电;提供 Android 平台下应用弹幕集成的解决方案。

华为视频服务属于此类。

  1. 个人或团队开发者提供的开源的SDK,开发者可以三两行代码就能集成到应用中的视频播放框架,并且提供了开放的接口来满足不同开发者的不同需求。

其中1,2是Android原生自带的组件,只能播放简单的mp4,3gp几种格式,无法播放flv,rmvb等格式。所以更多的开发者选择开源的SDK来支持更多的视频格式以及播放能力。

3-整体流程

视频流从加载到准备播放需要解协议,解封装,解编码这样的过程,下图是视频播放整个流程需要涉及到的步骤:

在这里插入图片描述

协议就是流媒体协议:一般由http,RTSP,RTMP;一般常见的使用http协议,而RTSP和RTMP一般用于直播流或支持带有控制信令的,比如远程视频监控

视频封装协议指的是我们常见的mp4,avi,rmvb,mkv,ts,3gp,flv等常见后缀格式,他们就是流媒体封装协议,就是在传输过程中把音频和视频打包在一起,所以播放前需要解开,提取对应的音频编码和视频编码,

Ø 音频编码:

音频数据的编码方式,常见的mp3,pcm,wav,aac,ac-3等,因为音频的原始数据大小一般不适合直接传入,原始大小一般按照

取样率(Sampling Rate)Channel(s)声道数样本格式*时长去计算,假设音频采样率是48kHz,样本格式是16bit,单声道,24s,原始音频大小

48000161*24/8 = 2.3mb

而实际将音频信息提取出来的大小,如下图大概只有353K,这就是音频编码的作用。

在这里插入图片描述

Ø 视频编码:
视频编码指的就是画面图像的编码压缩方式,一般有 H263、H264、HEVC(H265)、MPEG-2 、MPEG-4 等,其中H264 是目前比较常见的编码方式。视频编码的原理比较复杂,这里不单独讲了,目的是相同的,视频编码主要为了实现视频信息的压缩。

知识点:硬解码和软解码
我们在一些播放器中会看到,有硬解码和软解码两种播放形式给我们选择, 他们有什么区别呢?

手机有CPU、GPU或者解码器等硬件。通常,我们的计算都是在CPU上进行的,也就是我们软件的执行芯片,而GPU主要负责画面的显示(是一种硬件加速)。

所谓软解码,就是指利用CPU的计算能力来解码,通常如果CPU的能力不是很强的时候,一则解码速度会比较慢,二则手机可能出现发热现象。但是,由于使用统一的算法,兼容性会很好。

硬解码,指的是利用手机上专门的解码芯片来加速解码。通常硬解码的解码速度会快很多,但是由于硬解码由各个厂家实现,质量参差不齐,非常容易出现兼容性问题。

4-集成关键步骤说明和代码

4.1-Android原生方式

这里以VideoView为例,VidoView本身其实就是打包了SurfaceView和MediaPlayer。

步骤1:布局中增加VideoView


<LinearLayout  

android:layout_width="match_parent"  

android:layout_height="200dp">  

<VideoView  

android:id="@+id/videoView"  

android:layout_width="wrap_content"  

android:layout_height="wrap_content">  

</VideoView>  

</LinearLayout>  

步骤2:设置播放源及控制器

//网络视频    

String netVideoUrl = "http://baobab.kaiyanapp.com/api/v1/playUrl?vid=221119&resourceType=video&editionType=default&source=aliyun&playUrlType=url_oss&udid=1111";    

//指定视频文件的路径    

videoView.setVideoURI(Uri.parse(videoUrl1));    

//设置视频控制器    

videoView.setMediaController(new MediaController(this));    

//播放完成回调    

videoView.setOnCompletionListener( new MyPlayerOnCompletionListener()); 

步骤3:添加播放,暂停等按钮控制播放

switch (v.getId()){    

case R.id.play:    

if(!videoView.isPlaying()){ //开始播放    

Log.d(TAG, "onClick: play video");    

videoView.start();    

}    

break;    

case R.id.pause:    

Log.d(TAG, "onClick: pause video");    

if(videoView.isPlaying()){//暂停    

videoView.pause();    

}    

break;    

case R.id.replay:    

Log.d(TAG, "onClick: repaly video");    

if(videoView.isPlaying()){    

videoView.resume();//重新播放    

}    

break;   

步骤4:增加onDestroy,释放资源

public void onDestroy(){//释放资源  

super.onDestroy();  

if(videoView!=null){  

videoView.suspend();  

}  

}  

视频播放效果:

在这里插入图片描述

4.2-集成第三方开源SDK方式

这里以开源的JZVideo为例, github地址: https://github.com/Jzvd/JZVideo

这里使用了ListView方式实现多个视频播放源的列表式播放。

步骤1- 在app下面的build.gradle的dependencies包中添加

implementation 'cn.jzvd:jiaozivideoplayer:7.5.0'

步骤2- 布局中使用cn.jzvd.JzvdStd

<?xml version="1.0" encoding="utf-8"?>  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

android:orientation="vertical"  

android:layout_width="match_parent"  

android:layout_height="wrap_content">  

<cn.jzvd.JzvdStd  

android:id="@+id/item_jz_video"  

android:layout_width="match_parent"  

android:layout_height="200dp"/>  

</RelativeLayout>  

</LinearLayout>  

步骤3-代码中设置播放地址和播放源


class ViewHolder{  

JzvdStd jzvdStd;  

public ViewHolder(View view){  

jzvdStd = view.findViewById(R.id.item_jz_video);  

}  

}      

jzvdStd = view.findViewById(R.id.item_jz_video);  

//设置视频播放源,第1个参数是视频url,第2个参数是title,  

viewHolder.jzvdStd.setUp(  

videoUrls[position],  

videoTitles[position], Jzvd.SCREEN_NORMAL);  

//设置视频的缩略图  

Glide.with(convertView.getContext())  
     .load(videoposters[position])  
     .into(viewHolder.jzvdStd.posterImageView);  

//记录播放的位置  

viewHolder.jzvdStd.positionInList = position;  
   
//增加释放视频资源onStop方法  

@Override  

protected void onStop() {  

super.onStop();  

JzvdStd.releaseAllVideos();  

}  

视频播放效果:

在这里插入图片描述

JzvdStd特点:实现滚动ListView后视频停止播放,视频最大化,自动缓冲,后台纯音播放,可设置缩略图,可设置视频标题,视频自动调节亮度,声音。

4.3-集成华为视频服务的方式

布局可是使用SurfaceView、TextureView,集成华为视频服务SDK,SDK依赖如下:

implementation "com.huawei.hms:videokit-player:1.0.1.300"

基本播放流程

在这里插入图片描述

步骤 1:初始化播放器

把视频服务的进程先拉起来,它是运行在独立的进程里面的,进程拉起来之后会有个回调,成功的话会有个onSuccess回调 ,生成SDK的实例。

应用开始的时候只要调用初始化一次

/** 

*Inittheplayer 

*/  

privatevoidinitPlayer(){  

//DeviceIdtestisusedinthedemo,specificaccesstoincomingdeviceIdafterencryption  
  WisePlayerFactoryOptionsfactoryOptions=newWisePlayerFactoryOptions.Builder().setDeviceId("xxx").build();  

WisePlayerFactory.initFactory(this,factoryOptions,initFactoryCallback);  

  }  
/** 

*Playerinitializationcallback 

*/  

privatestaticInitFactoryCallbackinitFactoryCallback=newInitFactoryCallback(){  

@Override  

publicvoidonSuccess(WisePlayerFactorywisePlayerFactory){  

LogUtil.i(TAG,"initplayerfactorysuccess");  

setWisePlayerFactory(wisePlayerFactory);  

  }  

 };  

每次切换一个片源,Step2-Step8都要重新做

步骤 2:创建播放实例,

Private void initPlayer(){  

if(VideoKitPlayApplication.getWisePlayerFactory()==null){  

return;  

  }  

wisePlayer=VideoKitPlayApplication.getWisePlayerFactory().createWisePlayer();  

}  

步骤 3:设置监听器

创建实例后,要把监听器添加到sdk中,

主要的监听器有

1-错误监听请求网络出错,解码出错,监听会把消息抛给app,

2-和消息监听:播放过程中网速太低,就会有消息通知

3-Onnet监听:下载数据之后回调,通知当前数据已经开始下载,获取播放时长等信息,

4-分辨率更新监听,播放内容分辨率变化,有会通知

privatevoidsetPlayListener(){  

if(wisePlayer!=null){  

wisePlayer.setErrorListener(onWisePlayerListener);  

wisePlayer.setEventListener(onWisePlayerListener);  

wisePlayer.setResolutionUpdatedListener(onWisePlayerListener);  

wisePlayer.setReadyListener(onWisePlayerListener);  

wisePlayer.setLoadingListener(onWisePlayerListener);  

wisePlayer.setPlayEndListener(onWisePlayerListener);  

wisePlayer.setSeekEndListener(onWisePlayerListener);  

}  
 }  

步骤 4:设置播放源

//设置单个播放地址  

wisePlayer.setPlayUrl("http://baobab.kaiyanapp.com/api/v1/playUrl?vid=221119&resourceType=video&editionType=default&source=aliyun&playUrlType=url_oss&udid=1111");  

步骤5:设置视频播放窗口

publicvoidsetSurfaceView(SurfaceViewsurfaceView){  

if(wisePlayer!=null){  

wisePlayer.setView(surfaceView);  

 }  

}   

步骤6:请求数据缓冲

wisePlayer.ready();//开始请求数据

视频播放效果:

在这里插入图片描述

5-其他

5.1-Android原生,第三方SDK,HMS Video SDK 对比

在这里插入图片描述

相比较而言,当前华为视频服务提供的能力比Android原生的VideoView以及Surface+MediaPlayer要强大,但是相比开源的SDK在播放功能和支持的视频编码上还有增强的地方;大部分功能也在未来规划之中,除了播放能力的增强,华为视频服务还将提供长,短视频及直播的端到端解决方案能力,包括视频编辑,直播录制,视频分发,视频托管,视频审核,视频加密等,这些能力将助力CP实现快速的媒体类APP的集成上线,基于未来的能力演进,推荐使用华为视频服务。

缩写表:

在这里插入图片描述


原文链接:https://developer.huawei.com/consumer/cn/forum/topic/0202440181902250357?fid=18

原作者:胡椒

posted @ 2021-01-26 14:15  华为开发者论坛  阅读(3358)  评论(0编辑  收藏  举报