1. 程式人生 > >SeekBar與MediaPlayer(生命週期)的seekTo()問題

SeekBar與MediaPlayer(生命週期)的seekTo()問題

> MediaPlayer的原理 Android;基於Stagefight的MediaPLayer框架的結構
Android MediaPlayer 及 NativePlayer 之播放格式對比- https://blog.csdn.net/andyhuabing/article/details/40855955
Android MediaPlayer的主要具體實現在OpenCore的Player中.Android的MediaPlayer包含了Audio和video的播放功能.
  MediaPlayer在底層是基於OpenCore(PacketVideo)的庫實現的,為了構建一個MediaPlayer程式,上層還包含了程序間通訊等內容,這種程序間通訊的基礎是Android基本庫中的Binder機制。 

-- Android官方公佈的文件顯示MediaPlayer支援如下視訊格式:
Video H.263 X X 3GPP (.3gp) and MPEG-4 (.mp4)
H.264 AVC X 3GPP (.3gp) and MPEG-4 (.mp4)
MPEG-4 SP X 3GPP (.3gp)

> MediaPlayer生命週期
音訊開發ijkplayer小結 android- http://www.jianshu.com/p/55fbfd5b564a
Android MediaPlayer各種狀態切換- http://blog.sina.com.cn/s/blog_63f5ae1a0100zajv.html
Android MediaPlayer的生命週期- http://blog.csdn.net/ddna/article/details/5178864
MediaPlayer的生命週期以及狀態轉換- http://blog.csdn.net/songshizhuyuan/article/details/32947139
Android MediaPlayer生命週期及狀態說明- http://blog.csdn.net/biaobiao1217/article/details/51557733

  1.MediaPlayer.OnPreparedListener:MediaPlayer進入準備完成的狀態觸發,表示媒體可以開始播放了。
  2.MediaPlayer.OnSeekCompleteListener:呼叫MediaPlayer的seekTo方法後,MediaPlayer會跳轉到媒體指定的位置,當跳轉完成時觸發。需要注意的時,seekTo並不能精確的挑戰,它的跳轉點必須是媒體資源的關鍵幀
  3.MediaPlayer.OnBufferingUpdateListener:網路上的媒體資源快取進度更新的時候會觸發。
  4.MediaPlayer.OnCompletionListener:媒體播放完畢時會觸發。但是當OnErrorLister返回false,或者MediaPlayer沒有設定OnErrorListener時,這個監聽也會被觸發。
  5.MediaPlayer.OnVideoSizeChangedListener:視訊寬高發生改變的時候會觸發。當所設定的媒體資源沒有視訊影象、MediaPlayer沒有設定展示的holder或者視訊大小還沒有被測量出來時,獲取寬高得到的都是0.
   6.MediaPlayer.OnErrorListener:MediaPlayer出錯時會觸發,無論是播放過程中出錯,還是準備過程中出錯,都會觸發。

-- 出錯後在重新初始化播放器並在Prepare監聽中根據邏輯加入如下,可在出錯前的那個position地方進行播放(方案如下):
long pos = 1000L * mCurrentVrVideoPosition / mTotalVrVideoPosition;
SeekBar.setProgress((int) pos);
mMediaPlayerWrapper.getPlayer().seekTo(mVideoSeekBar.getProgress() * mMediaPlayerWrapper.getPlayer().getDuration() / 1000);

> seekbar ,seekto
seekTo()的相關_android裡的mediaplayer- http://blog.csdn.net/some_that_loves/article/details/50533624
安卓 android seekbar 自定義滑塊 適合做音量調節  http://download.csdn.net/detail/u013506037/7944623
Android開發——MediaPlayer的seekto分析- http://blog.csdn.net/liuhui1905/article/details/7634416
 部分視訊源的問題。部分視訊播放時,呼叫seekTo的時候,會跳回到最開始的位置,這是因為視訊的關鍵幀的問題(GOP導致的),視訊壓縮比較高,而seek只支援關鍵幀,出現這個情況就是原始的視訊檔案中i幀比較少,目前針對此問題IjkPlayer無解

-- mediaPlayer的seekto方法:
使用步奏:
1.實現 OnSeekCompleteListener這個介面;
2.重寫onSeekComplete()這個方法,在這個方法裡面實現seekto()後的操作,通常是呼叫mediaplayer的star()t方法進行播放;
3.為mediaplayer設定setOnSeekCompleteListener(OnSeekCompleteListener  listener)監聽器;
4.呼叫mediaplayer的seekto(long arg0)這個方法就可以實現前進後退了,arg0引數表示音視訊檔案的毫秒數,設定到指定時間位置播放;
ps:1.有些媒體不支援Seek,例如直播流
        2.在播放狀態下才能實現監聽,也就是說播放的時候呼叫seekto()方法才會有效(個人測試結果)

seekto(position)中position位置不是關鍵幀;後退幾秒是為了找到關鍵幀開始播放。
其實 seekTo 跳轉的位置其實並不是引數所帶的 position,而是離 position 最近的視訊關鍵幀。
如果選擇第二種方式,要增加視訊的關鍵幀數量,可以推薦大家使用FFmpeg進行增加關鍵幀的處理工作。 

 -- FFmpeg 工具相關命令列語句:
 ffmpeg.exe -i "D:\in.mp4" -c:v libx264  -preset superfast -x264opts keyint=25 -acodec copy -f  mp4 "D:\out.mp4"
 命令語句大致意思是:在 D 盤路徑下把 in.mp4 視訊檔案每隔 25 幀設定一個關鍵幀,音軌保持原視訊引數,其餘使用 FFmpeg 提供的default 值,最後儲存為 out.mp4 檔案到 D 盤。 

 很多情況下都選擇盲目地替換不同的視訊元件出實現,而忽略了視訊原始檔本身的問題。
 關鍵幀與關鍵幀之間的動畫可以由軟體來建立,叫做過渡幀或者中間幀。
 關鍵幀的用途又分為:普通關鍵幀(用於處理圖形影象和動畫);動作指令碼關鍵幀(用於存放動作指令碼,關鍵幀可以通過動作指令碼控制flash影片和其中的影片剪輯);
 從原理上講,關鍵幀插值問題可歸結為引數插值問題,傳統的插值方法都可應用到關鍵幀方法中。但關鍵幀插值又與純數學的插值不同,它有其特殊性。一個好的關鍵幀插值方法必須能夠產生逼真的運動效果並能給使用者提供方便有效的控制手段。一個特定的運動從空間軌跡來看可能是正確的,但從運動學或動畫設計來看可能是錯誤的或者不合適的。使用者必須能夠控制運動的運動學特性,即通過調整插值函式來改變運動的速度和加速度。為了很好地解決插值過程中的時間控制問題,Steketee等提出了用雙插值的方法來控制運動引數。其中之一為位置樣條,它是位置對關鍵幀的函式;另一條為運動樣條,它是關鍵幀對時間的函式。Kochanek等提出了一類適合於keyframe系統的三次插值樣條,他們把關鍵幀處的切向量分成入向量和出向量兩部分,並引入三個引數:張量t、連續量c和偏移量b對樣條進行控制。該方法已在許多動畫系統中得到了應用.

 


--------------------- 
作者:desaco 
來源:CSDN 
原文:https://blog.csdn.net/shareus/article/details/78554225 
版權宣告:本文為博主原創文章,轉載請附上博文連結!