教你用三種方式打造一款簡單的網絡播放器


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

原作者:胡椒


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM