




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
【移動應用開發技術】Android音視頻深入十九使用ijkplayer做個視頻播放器(附源碼下載)
項目地址/979451341/Myijkplayer前段時候我覺得FFmpeg做個視頻播放器好難,雖然播放上沒問題,但暫停還有通過拖動進度條來設置播放進度,這些都即便做得到,可以那個延緩。。。。。現在學習一下目前移動端最知名的視頻播放器的框架ijkplayer,這個框架他是基于FFmpeg、SDL、還有安卓原生APIMediaCodec之類的。他是沒有播放界面的,這個需要我們去做,所以這個里我就做個基于ijkplayer的視頻播放器,隨便淺顯的說一下ijkplayer的源碼,關于ijkplayer的源碼以后會專門出一篇博客說一下。1.首先了解一下ijkplayer咋用我這里引入ijkplayer是通過添加依賴implementation'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
implementation'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
implementation'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
implementation'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
implementation'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
implementation'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
implementation'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'然后說說ijkplayer是如何播放視頻的ijkplayer每一次播放視頻都是通過創建Mediaplayer,然后賦值到一個接口類上,這里他創建的時候能夠挑選解碼的類型,是因為基于安卓原生APIMediaCodec的話是硬解,速度快、兼容差,如果是基于FFmpeg則是軟解,速度慢、兼容好,不過這個兼容問題,因為我們在引入依賴的時候把各個處理器相應的依賴,所以可以使用硬解,兼容問題基本都是手機處理器不同產生的。IjkMediaPlayerijkMediaPlayer=newIjkMediaPlayer();
ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);////開啟硬解碼ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"mediacodec",1);IMediaPlayermMediaPlayer=null;mMediaPlayer=ijkMediaPlayer;關于IjkMediaPlayer的源碼我只貼出一個函數的,從下面幾個loadLibrary看出來,他還是基于FFmpeg、SDL底層實現的。publicstaticvoidloadLibrariesOnce(IjkLibLoaderlibLoader){
Classvar1=IjkMediaPlayer.class;
synchronized(IjkMediaPlayer.class){
if(!mIsLibLoaded){
if(libLoader==null){
libLoader=sLocalLibLoader;
}
libLoader.loadLibrary("ijkffmpeg");
libLoader.loadLibrary("ijksdl");
libLoader.loadLibrary("ijkplayer");
mIsLibLoaded=true;
}
}
}好了,回到那個接口類的IMediaPlayer,源碼不多貼出來看一下,通過這些接口函數我們都可以知道這個ijkplayer如何使用我們都有了一個底,什么setDataSource、setDisplay,設置播放源、設置播放的屏幕信息。還有start、stop、pause,視頻播放的開始、停止、暫停,還有一大堆的接口,這些都是為了監聽播放器的狀態publicinterfaceIMediaPlayer{。。。。。。voidsetDisplay(SurfaceHoldervar1);
voidsetDataSource(Contextvar1,Urivar2)throwsIOException,IllegalArgumentException,SecurityException,IllegalStateException;
@TargetApi(14)
voidsetDataSource(Contextvar1,Urivar2,Map<String,String>var3)throwsIOException,IllegalArgumentException,SecurityException,IllegalStateException;
voidsetDataSource(FileDescriptorvar1)throwsIOException,IllegalArgumentException,IllegalStateException;
voidsetDataSource(Stringvar1)throwsIOException,IllegalArgumentException,SecurityException,IllegalStateException;
StringgetDataSource();
voidprepareAsync()throwsIllegalStateException;
voidstart()throwsIllegalStateException;
voidstop()throwsIllegalStateException;
voidpause()throwsIllegalStateException;
voidsetScreenOnWhilePlaying(booleanvar1);
intgetVideoWidth();
intgetVideoHeight();
booleanisPlaying();
voidseekTo(longvar1)throwsIllegalStateException;
longgetCurrentPosition();
longgetDuration();
voidrelease();
voidreset();
voidsetVolume(floatvar1,floatvar2);
intgetAudioSessionId();
MediaInfogetMediaInfo();
/**@deprecated*/
@Deprecated
voidsetLogEnabled(booleanvar1);
/**@deprecated*/
@Deprecated
booleanisPlayable();
voidsetOnPreparedListener(IMediaPlayer.OnPreparedListenervar1);
voidsetOnCompletionListener(IMediaPlayer.OnCompletionListenervar1);
voidsetOnBufferingUpdateListener(IMediaPlayer.OnBufferingUpdateListenervar1);
voidsetOnSeekCompleteListener(IMediaPlayer.OnSeekCompleteListenervar1);
voidsetOnVideoSizeChangedListener(IMediaPlayer.OnVideoSizeChangedListenervar1);
voidsetOnErrorListener(IMediaPlayer.OnErrorListenervar1);
voidsetOnInfoListener(IMediaPlayer.OnInfoListenervar1);
voidsetOnTimedTextListener(IMediaPlayer.OnTimedTextListenervar1);
voidsetAudioStreamType(intvar1);
/**@deprecated*/
@Deprecated
voidsetKeepInBackground(booleanvar1);
intgetVideoSarNum();
intgetVideoSarDen();
/**@deprecated*/
@Deprecated
voidsetWakeMode(Contextvar1,intvar2);
voidsetLooping(booleanvar1);
booleanisLooping();
ITrackInfo[]getTrackInfo();
voidsetSurface(Surfacevar1);
voidsetDataSource(IMediaDataSourcevar1);
publicinterfaceOnTimedTextListener{
voidonTimedText(IMediaPlayervar1,IjkTimedTextvar2);
}
publicinterfaceOnInfoListener{
booleanonInfo(IMediaPlayervar1,intvar2,intvar3);
}
publicinterfaceOnErrorListener{
booleanonError(IMediaPlayervar1,intvar2,intvar3);
}
publicinterfaceOnVideoSizeChangedListener{
voidonVideoSizeChanged(IMediaPlayervar1,intvar2,intvar3,intvar4,intvar5);
}
publicinterfaceOnSeekCompleteListener{
voidonSeekComplete(IMediaPlayervar1);
}
publicinterfaceOnBufferingUpdateListener{
voidonBufferingUpdate(IMediaPlayervar1,intvar2);
}
publicinterfaceOnCompletionListener{
voidonCompletion(IMediaPlayervar1);
}
publicinterfaceOnPreparedListener{
voidonPrepared(IMediaPlayervar1);
}}2.寫界面全屏播放,潛入式//正真的全屏,隱藏了狀態欄、AtionBar、導航欄
@Override
publicvoidonWindowFocusChanged(booleanhasFocus){
super.onWindowFocusChanged(hasFocus);
if(hasFocus&&Build.VERSION.SDK_INT>=19){
ViewdecorView=getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|View.SYSTEM_UI_FLAG_FULLSCREEN
|View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}然后上下兩個欄目,負責一些播放器的控制,頂部負責設置返回、設置按鈕,底部需要設置播放/暫停按鈕、播放進度條、停止按鈕<com.example.zth.two.VideoPlayerIJK
android:id="@+id/ijk_player"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include
android:id="@+id/include_play_top"
layout="@layout/include_play_top"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<include
android:id="@+id/include_play_bottom"
layout="@layout/include_play_bottom"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="50dp"/>關于上下兩個欄目在用戶觀看視頻時需要隱藏,在用戶點擊屏幕則顯示兩個欄目,供用戶使用這個則是需要通過計時器來完成記錄目前距離上一次用戶點擊屏幕的時間,如果視頻超過3秒,則隱藏欄目,如果點擊屏幕則恢復,關于隱藏和恢復使用Animation來完成。timer=newTimer();
timerTask=newTimerTask(){
@Override
publicvoidrun(){
longt=System.currentTimeMillis();
if(t-time>3000&&menu_visible){
time=t;
handler.post(newRunnable(){
@Override
publicvoidrun(){
Animationanimation=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move_bottom);
rl_bottom.startAnimation(animation);
Animationanimation_top=AnimationUtils.loadAnimation(getApplicationContext(),R.anim.move_top);
rl_top.startAnimation(animation_top);
menu_visible=false;
}
});
}
}
};還需要加載框,這個在視頻加載完的接口回調里隱藏他<ProgressBar
android:id="@+id/pb_loading"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:layout_marginTop="60dp"
android:indeterminate="false"
android:indeterminateDrawable="@drawable/video_loading"
android:padding="5dp"/>3.播放實現這里我是使用了一個另一個博主封裝的ijkplayer的類說一下這個類的運行過程一開始創建MediaPlayer做一些配置,賦值給一個接口類,并且暴露了接口IjkMediaPlayerijkMediaPlayer=newIjkMediaPlayer();
ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);////開啟硬解碼ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"mediacodec",1);mMediaPlayer=ijkMediaPlayer;
if(listener!=null){
mMediaPlayer.setOnPreparedListener(listener);
mMediaPlayer.setOnInfoListener(listener);
mMediaPlayer.setOnSeekCompleteListener(listener);
mMediaPlayer.setOnBufferingUpdateListener(listener);
mMediaPlayer.setOnErrorListener(listener);
}然后設置播放源,這個播放源能夠是本地視頻路徑、網絡視頻url、還可以是網絡RTMP推流url,還要講SurfaceView的配置信息給他try{
mMediaPlayer.setDataSource(mPath);
}catch(IOExceptione){
e.printStackTrace();
}
//給mediaPlayer設置視圖
mMediaPlayer.setDisplay(surfaceView.getHolder());
mMediaPlayer.prepareAsync();想開始播放就調用IMediaPlayer的那些控制函數publicvoidstart(){
if(mMediaPlayer!=null){
mMediaPlayer.start();
}
}還有關于activity的生命周期控制,其中native_profileEnd就相當于很智能的暫停,當屏幕回的時候就繼續播放視頻。@Override
protectedvoidonStop(){
IjkMediaPlayer.native_profileEnd();
handler.removeCallbacksAndMessages(null);
super.onStop();
}結束Activity的時候就停止播放視頻并釋放資源@Override
protectedvoidonDestroy(){
if(ijkPlayer!=null){
ijkPlayer.stop();
ijkPlayer.release();
ijkPlayer=null;
}
super.onDestroy();
}最后還有播放進度,我這里是通過handler自己調用自己循環更新播放時間顯示和進度條handler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
caseMSG_REFRESH:
if(ijkPlayer.isPlaying()){
refresh();
handler.sendEmptyMessageDelayed(MSG_REFRESH,1000);
}
break;
}
}
};
privatevoidrefresh(){
longcurrent=ijkPlayer.getCurrentPosition()/1000;
longduration=ijkPlayer.getDuration()/1000;
Log.v("zzw",current+""+duration);
longcurrent_second=current%60;
longcurrent_minute=current/60;
longtotal_second=duration%60;
longtotal_minute=dur
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 溫州住宅裝修合同范本
- 欠款分期償還合同范本
- 商店房屋租賃合同范本
- 學校宿舍合同范本
- 租用公司資質合同范本
- 防汛物資供貨合同范本
- 酒店維修勞務合同范本
- 病句表意不明30題及答案
- 企業宣傳與介紹模板
- 2025智能樓宇自動化控制系統廣告宣傳合同范本
- 第八課 良師相伴 亦師亦友
- 全國高考物理高考題說題比賽一等獎課件物理說題李煥景
- 華為MA5800配置及調試手冊
- 巴金名著導讀《寒夜》
- 2024年建筑業10項新技術
- 《環境建設工程概算、預算編制辦法》
- 提升服務行業人員的職業道德和職業素養
- 按摩椅行業分析及市場前景展望報告
- 2024年上海外服招聘筆試參考題庫附帶答案詳解
- 改善患者就醫體驗培訓課件
- 養殖烏龜入門知識培訓課件
評論
0/150
提交評論