zoukankan      html  css  js  c++  java
  • 教你用三种方式打造一款简单的网络播放器

    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

    原作者:胡椒

  • 相关阅读:
    后端开发-IDEA-SSM框架-mapper扫描
    测试软件注意事项
    字符串中重复最多的字符及重复次数
    【windows】server2012R2 服务器的日志出现大量Windows安全日志事件ID 4625
    【办公】管理员已阻止你运行此应用。有关详细信息,请与管理员联系。windows10
    【linux】dellR420更换系统盘,重做系统
    【mysql】MySQL InnoDB 表损坏,显示错误: “MySQL is trying to open a table handle but the .ibd file for table ### does not exist”
    【linux】服务器的网站后台无法上传图片报错error‘8’,云锁文件删除无法删除
    【linux】记录一次服务器无法使用ssh 错误修改文件导致服务器无法启动
    【linux】nginx访问量统计
  • 原文地址:https://www.cnblogs.com/developer-huawei/p/14330044.html
Copyright © 2011-2022 走看看