使用VideoView開發視頻總結,videoview開發視頻
一、VideoView及其相關組件總結
在Android中,播放視頻有2種方式,第一種方式是使用MediaPlayer結合SurfaceView來播放,通過MediaPlayer來控制視頻的播放、暫停、進度等,而通過SurfaceView來顯示視頻內容;第二種方式是使用VideoView來播放,這個類其實也是繼承了SurfaceView類,並且實現了MediaController.MediaPlayerController這個用於控制媒體播放的介面,另外在VideoView上還有一個用於對媒體播放進行控制的面板,包括快進、快退、播放、暫停按鈕以及一個進度條。使用VideoView播放視頻的好處是簡單因為它已經幫我們實現了SurfaceView以及控制方法,開發過程中只需直接拿來使用就可以了,但它的缺點是不夠靈活。而是用MediaPlayer結合SurfaceView來播放視頻的話,好處是可以更靈活的對其進行自訂,缺點是難度較大。
1.1
通過VideoView播放視頻步驟:
1、在介面布局檔案中定義VideoView組件,或在程式中建立VideoView組件
2、在Activity中擷取布局檔案中的組件並設定相應的監聽;
3、調用VideoView的如下兩個方法來載入指定的視頻:
(1)setVideoPath(String path):載入path檔案代表的視頻
(2)setVideoURI(URI uri):載入uri所對應的視頻
在使用setVideoURI(URI uri)方法之前要設定網路視頻路徑
4、調用VideoView的start()、pause()、resume()、stopPlayback()方法控制視頻的播放(開始、暫停、繼續、停止),VideoView的getDuration()可以返回視頻的長度,可以結合VideoView的resume()方法進行記憶播放和緩衝播放。
1.2 VideoView常用方法
Android VideoView類為我們提供了十分方便的視頻播放API,其主要方法有:
方法名稱 |
說明 |
void start() |
開始播放 |
void stopPlayback() |
停止播放 |
void pause() |
暫停 |
void resume() |
重新播放 |
void seekTo(int msec) |
從第幾毫秒開始播放 |
int getCurrentPosition() |
擷取當前播放位置 |
int getDuration() |
擷取當前視頻總長度 |
boolean isPlaying() |
當前VideoView是否在播放視頻 |
void setVideoPath(String path) |
以檔案路徑的方式設定VideoView播放的視頻源 |
void setVideoURI(URI uri) |
以Uri的方式設定視頻源,可以是網路Uri或本地Uri |
setMediaCotroller(MediaController controller) |
設定MediaController控制器 |
setOnCompletionListener(MediaPlayer.onCompletionListener l) |
監聽播放完成的事件 |
setOnErrorListener(MediaPlayer.OnErrorListener l) |
監聽播放發生錯誤時候的事件 |
setOnPreparedListener(MediaPlayer.OnPreparedListener l) |
監聽視頻裝載完成的事件 |
1.3 Media Controller類
Media Controller類為我們提供了一個懸浮的操作欄,包含了播放,暫停,快進,快退,上一個,下一個等功能鍵。還有拖動進度條至某一處也可以實現。在使用前VideoView和MeidaController需要相互指定控制項。
Mdedia Controller類包含的內建方法有:
方法名稱 |
說明 |
boolean isShowing() |
當前懸浮控制欄是否顯示。 |
void setMediaPlayer(MediaController.MediaPlayerControl player) |
設定控制的組件 |
void hide() |
隱藏MeidaController |
void show() |
顯示MeidaController |
void show(int timeout) |
設定MidiaController顯示的時間,以毫秒計算。如果設定為0則一直到調用hide()方法隱藏 |
void setPrevNextListeners(View.OnClickListener next,View.OnClickListener prev) |
設定上一個視頻下一個視頻的切換事件 |
預設情況下,Media Controller懸浮顯示3s後隱藏,觸摸響應的VideoView呼出。預設上一個,下一個按鈕隱藏。
1.4 視頻格式1.4.1 Android支援的視頻編碼格式
1.4.2 VideoView支援的影片格式
在實際測試中過程中,發現了一些由VideoView發出的Toast警告,內容寫著不支援影片格式,以致無法播放。VideoView僅能播放progressive streamable(漸進式流)的影片,一般的mp4或3gp若不採用progressive streamable模式轉檔案的影片,是無法被VideoView通過網路播放的,但假如存放在local端(如儲存卡)則不在此限。
1.5 VideoView的監聽處理
開發過程中使用的VideoView監聽一共有3個:setOnCompletionListener(MediaPlayer.onCompletionListener l)、setOnErrorListener(MediaPlayer.OnErrorListener l)、setOnPreparedListener(MediaPlayer.OnPreparedListener l)
1.5.1 setOnCompletionListener(MediaPlayer.onCompletionListener l)
setOnCompletionListener(MediaPlayer.onCompletionListener l)用於監聽視頻播放完成後的事件
1.5.2 setOnErrorListener(MediaPlayer.OnErrorListener l)
setOnErrorListener(MediaPlayer.OnErrorListener l)用於監聽VideoView在使用過程中出現的各種錯誤。
錯誤常數:
- MEDIA_ERROR_IO
- 檔案不存在或錯誤,或網路不可訪問錯誤
- 值: -1004 (0xfffffc14)
- MEDIA_ERROR_MALFORMED
- 流不符合有關標準或檔案的編碼規範
- 值: -1007 (0xfffffc11)
- MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK
- 視頻流及其容器不適用於連續播放視頻的指標(例如:MOOV原子)不在檔案的開始.
- 值: 200 (0x000000c8)
- MEDIA_ERROR_SERVER_DIED
- 媒體伺服器掛掉了。此時,程式必須釋放MediaPlayer 對象,並重新new 一個新的。
- 值: 100 (0x00000064)
- MEDIA_ERROR_TIMED_OUT
- 一些操作使用了過長的時間,也就是逾時了,通常是超過了3-5秒
- 值: -110 (0xffffff92)
- MEDIA_ERROR_UNKNOWN
- 未知錯誤
- 值: 1 (0x00000001)
- MEDIA_ERROR_UNSUPPORTED
- 位元流符合相關編碼通訊協定或檔案的規格,但媒體架構不支援此功能
- 值: -1010 (0xfffffc0e)
- what int: 標記的錯誤類型:
- MEDIA_ERROR_UNKNOWN
- MEDIA_ERROR_SERVER_DIED
- extra int: 標記的錯誤類型.
- MEDIA_ERROR_IO
- MEDIA_ERROR_MALFORMED
- MEDIA_ERROR_UNSUPPORTED
- MEDIA_ERROR_TIMED_OUT
- MEDIA_ERROR_SYSTEM (-2147483648) - low-level system error.
1.5.3 setOnPreparedListener(MediaPlayer.OnPreparedListener l)
setOnPreparedListener(MediaPlayer.OnPreparedListener l)用於監聽視頻裝在完成後的事件
二、視頻旋轉
在網上查詢了眾多的關於旋轉螢幕的方法。總結起來可以分為4種。在介紹之前要先瞭解預設情況下Android旋轉螢幕機制(當然是在手機本身旋轉螢幕功能開啟的時候才能實現,自己在開發過程中一直發現開發視頻不能隨著手機一起旋轉,弄了幾個小時才發現是自己Android本身內建的旋轉按鈕沒有開啟):
預設情況下,當使用者的重力感應器開啟後,旋轉螢幕方向會導致當前activity發生onDestory->onCreate,這樣會重新構造當前activity和介面布局,如果是在Camera介面,則表現為卡頓或者黑屏一段時間。如果是在橫豎屏UI設計方面,那麼想很好的支援旋轉螢幕,則建議在res中建立layout-land和layport兩個檔案夾,把橫屏和豎屏的檔案分別放入對應的layout檔案夾中。
2.1 AndroidMainfest.xml設定
如果單單想設定橫屏或者豎屏,那麼只需添加橫豎屏代碼:
優點:即使旋轉螢幕,Actiity也不會重新onCreate。
缺點:螢幕只有一個方向
2.2 代碼動態設定
如果需要動態改變橫豎屏設定,只要在代碼中調用setRequestedOrientation()函數:
優點:可以隨意動態設定,滿足人們為改變橫豎屏的要求,同時滿足橫豎屏UI不同的設計需求
缺點:如果改變設定,那麼Activity會被銷毀,重新構建,即重新onCreate;
2.3 重寫onCongigurationChanged
使用此方法可以避免旋轉螢幕時Activity被不斷的onCreate情況(這種情況下往往造成螢幕切換時的卡頓)。
首先,在AndroidMainfest.xml中添加configChanges:
注意:keyboardHidden表示鍵盤協助工具功能隱藏,如果你的開發API等級等於或高於13,還需要設定screenSize,因為screenSize會在旋轉螢幕時改變
然後,在Activity中重寫onConfigurationChanged方法,這個方法將會在旋轉螢幕變化時,進行監聽處理:
優點:可以隨時監聽旋轉螢幕變化,並對應做出相應操作
缺點:它只能一次旋轉90°,如果一下子旋轉180°,onConfigurationChanged函數不會被調用。
2.4
結合OrientationEventListener,自訂旋轉監聽設定
這種方法由於自訂回掉介面暫時不明白,在這裡暫不總結。
可以參考網站:http://www.jb51.net/article/64735.htm
三、誤按返回操作
為了防止使用者誤按返回鍵而退出播放,可以在程式中重寫onKeyDown方法。在這個方法中來處理使用者點擊返回鍵的動作:例如只有使用者在短時間內點擊兩次返回鍵才真正退出播放。
四、設定手機全屏4.1 最常用的設定全屏方法
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 設定無標題 requestWindowFeature(Window.FEATURE_NO_TITLE); // 設定全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main);}
使用上述方法注意:requestWindowFeature()方法一定要在setContentView()前面,否則會報錯;
4.2 AndroidManifest中配置
利用Android提供的內建的Theme就可以了。
五、設定螢幕顯示方向
當不定義橫豎屏的情況下,這個app會隨著手機的轉向設定變化而變化,而我們對於橫豎屏切換肯定要做相應的事情,可以如下方法去做:
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { // 處理橫屏下要做的事 } else { // 處理豎屏下要做的事情 }
在這個視頻軟體中我要做到一個點擊按鈕讓手機旋轉的功能,就是用到了上面的代碼:
六、取消全屏的方法
getWindow().clearFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN);
七、Android系統內建樣式
android:theme="@android:style/Theme.Dialog" 將一個Activity顯示為能話框模式
android:theme="@android:style/Theme.NoTitleBar" 不顯示應用程式標題欄
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 不顯示應用程式標題欄,並全屏
android:theme="Theme.Light" 背景為白色
android:theme="Theme.Light.NoTitleBar" 白色背景並無標題列
android:theme="Theme.Light.NoTitleBar.Fullscreen" 白色背景,無標題列,全屏
android:theme="Theme.Black" 背景黑色
android:theme="Theme.Black.NoTitleBar" 黑色背景並無標題列
android:theme="Theme.Black.NoTitleBar.Fullscreen" 黑色背景,無標題列,全屏
android:theme="Theme.Wallpaper" 用系統案頭為應用程式背景
android:theme="Theme.Wallpaper.NoTitleBar" 用系統案頭為應用程式背景,且無標題列
android:theme="Theme.Wallpaper.NoTitleBar.Fullscreen" 用系統案頭為應用程式背景,無標題列,全屏
android:theme="Translucent" 透明背景
android:theme="Theme.Translucent.NoTitleBar" 透明背景並無標題
android:theme="Theme.Translucent.NoTitleBar.Fullscreen" 透明背景並無標題,全屏
android:theme="Theme.Panel" 面板風格顯示
android:theme="Theme.Light.Panel" 平板風格顯示
八、小結:
由於太久的時間沒有接觸Android開發,很多Android開發的東西都忘記了,代碼中具體的方法在這裡不做一一總結,而在另外一篇文檔中總結說明。