Android音視頻開發(fā)之VideoView使用指南
VideoView介紹
之前介紹過使用MediaPlayer
+SurfaceView
實現(xiàn)播放視頻功能。無意間發(fā)現(xiàn)官方封裝了VideoView
組件來實現(xiàn)簡單視頻播放功能,內(nèi)部同樣是使用MediaPlayer
+SurfaceView
的形式控制MediaPlayer
對視頻文件進(jìn)行播放。使用場景比較簡單,適用于只是播放視頻的場景,其提供能力有限不太適合使用在調(diào)節(jié)視頻亮度等其他功能。
MediaController
除了播放組件VideoView
外還有MediaController
組件為視頻播放提供播放操作欄功能,可支持視頻播放、暫停、快進(jìn)、快退等功能。另外還提供進(jìn)度條功能可以拖拽到指定位置進(jìn)行播放視頻。
使用
VideoView
封裝了MediaPlayer
同樣也提供了類似于MediaPlayer
的api。例如start
方法同樣是播放視頻功能,但調(diào)用該方法前最好也是通過設(shè)置setOnpreparedListener
回調(diào)結(jié)果來執(zhí)行,當(dāng)調(diào)用setVideoPath
后會主動執(zhí)行prepareAsync
方法。在VideoView
內(nèi)部幫助開發(fā)者封裝實現(xiàn)了很多功能,其實也能借鑒其內(nèi)部源碼來實現(xiàn)功能更全面功能更完備的自制播放器。
常用Api | 說明 |
---|---|
setVideoPath | 設(shè)置視頻資源 |
start | 播放 |
pause | 暫停 |
resume | 重播 |
seekTo | 指定位置播放 |
isPlaying | 視頻是否播放 |
getCurrentPosition | 獲取當(dāng)前播放位置 |
setMediaController | 設(shè)置MediaController |
setOnpreparedListener | 監(jiān)聽視頻裝載完成事件 |
// 實例化videoView videoView = new VideoView(this); Uri uri = Uri.fromFile(new File("sdcard/DCIM","新世紀(jì)福音戰(zhàn)士24.mp4")); //加載視頻資源 videoView.setVideoURI(uri); LinearLayout linearLayout = new LinearLayout(this); linearLayout.addView(videoView); setContentView(linearLayout); //設(shè)置監(jiān)聽 videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { //回調(diào)成功并播放視頻 videoView.start(); } }); //創(chuàng)建操作欄 MediaController mediaController = new MediaController(this); videoView.setMediaController(mediaController); mediaController.setMediaPlayer(videoView);
源碼分析
既然封裝了VideoView
和MediaController
兩者組件,在使用過程中也發(fā)現(xiàn)了許多之前嘗試實現(xiàn)的一些功能看看他們又是如何實現(xiàn)的。
進(jìn)度顯示
MediaController
顯示時調(diào)用show
方法內(nèi)部可以看到一個post(mShowProgress);
方法
public void show(int timeout) { if (!mShowing && mAnchor != null) { setProgress(); if (mPauseButton != null) { mPauseButton.requestFocus(); } disableUnsupportedButtons(); updateFloatingWindowLayout(); mWindowManager.addView(mDecor, mDecorLayoutParams); mShowing = true; } updatePausePlay(); // cause the progress bar to be updated even if mShowing // was already true. This happens, for example, if we're // paused with the progress bar showing the user hits play. post(mShowProgress); if (timeout != 0 && !mAccessibilityManager.isTouchExplorationEnabled()) { removeCallbacks(mFadeOut); postDelayed(mFadeOut, timeout); } }
可以看到mShowProgress
是一個Runnable
,內(nèi)部會延遲不停調(diào)用自己來更新setProgress()
。setProgress()
方法就是讀取MediaPlayer
播放進(jìn)度從而更新播放信息。
private final Runnable mShowProgress = new Runnable() { @Override public void run() { int pos = setProgress(); if (!mDragging && mShowing && mPlayer.isPlaying()) { postDelayed(mShowProgress, 1000 - (pos % 1000)); } } };
播放尺寸適配
之前自定義實現(xiàn)播放尺寸適配,在VideoView
內(nèi)部直接幫助開發(fā)者實現(xiàn)視頻播放適配,詳細(xì)代碼可以直接看onMeasure
重寫。代碼大致算法就是通過比較VideoView
布局寬高和視頻的寬高進(jìn)行比例比較來重寫計算VideoView
的寬高。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", " // + MeasureSpec.toString(heightMeasureSpec) + ")"); int width = getDefaultSize(mVideoWidth, widthMeasureSpec); int height = getDefaultSize(mVideoHeight, heightMeasureSpec); if (mVideoWidth > 0 && mVideoHeight > 0) { int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) { // the size is fixed width = widthSpecSize; height = heightSpecSize; // for compatibility, we adjust size based on aspect ratio if ( mVideoWidth * height < width * mVideoHeight ) { //Log.i("@@@", "image too wide, correcting"); width = height * mVideoWidth / mVideoHeight; } else if ( mVideoWidth * height > width * mVideoHeight ) { //Log.i("@@@", "image too tall, correcting"); height = width * mVideoHeight / mVideoWidth; } } else if (widthSpecMode == MeasureSpec.EXACTLY) { // only the width is fixed, adjust the height to match aspect ratio if possible width = widthSpecSize; height = width * mVideoHeight / mVideoWidth; if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) { // couldn't match aspect ratio within the constraints height = heightSpecSize; } } else if (heightSpecMode == MeasureSpec.EXACTLY) { // only the height is fixed, adjust the width to match aspect ratio if possible height = heightSpecSize; width = height * mVideoWidth / mVideoHeight; if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) { // couldn't match aspect ratio within the constraints width = widthSpecSize; } } else { // neither the width nor the height are fixed, try to use actual video size width = mVideoWidth; height = mVideoHeight; if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) { // too tall, decrease both width and height height = heightSpecSize; width = height * mVideoWidth / mVideoHeight; } if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) { // too wide, decrease both width and height width = widthSpecSize; height = width * mVideoHeight / mVideoWidth; } } } else { // no size yet, just adopt the given spec sizes } setMeasuredDimension(width, height); }
到此這篇關(guān)于Android音視頻開發(fā)之VideoView使用指南的文章就介紹到這了,更多相關(guān)Android VideoView內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android UniversalVideoView實現(xiàn)視頻播放器
- Android自定義videoview仿抖音界面
- Android原生視頻播放VideoView的使用
- android多媒體類VideoView使用方法詳解
- Android編程實現(xiàn)VideoView循環(huán)播放功能的方法
- Android多媒體之VideoView視頻播放器
- Android VideoView類實例講解
- Android使用VideoView播放本地視頻和網(wǎng)絡(luò)視頻的方法
- android使用videoview播放視頻
- Android中VideoView音視頻開發(fā)的實現(xiàn)
相關(guān)文章
Android使用fastjson庫解析json字符串實戰(zhàn)
fastjson是一個Java語言編寫的高性能功能完善的JSON庫,它采用一種“假定有序快速匹配”的算法,把JSON?Parse的性能提升到極致,是目前Java語言中最快的JSON庫,Fastjson接口簡單易用,已經(jīng)被廣泛使用在緩存序列化、協(xié)議交互、Web輸出、Android客戶端等多種應(yīng)用場景2023-11-11Android Selector 按下修改背景和文本顏色的實現(xiàn)代碼
這篇文章主要介紹了Android Selector 按下修改背景和文本顏色的實現(xiàn)代碼,本文通過實例代碼和demo展示給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11Android中判斷是否聯(lián)網(wǎng)實現(xiàn)代碼
這篇文章主要介紹了Android中判斷是否聯(lián)網(wǎng)實現(xiàn)代碼,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下2015-06-06Android Studio 多層級 Module 對 aar 引用問題解決方法
這篇文章主要介紹了Android Studio 多層級 Module 對 aar 引用問題的解決方法,需要的朋友參考下2017-12-12Android App更改應(yīng)用的圖標(biāo)的實現(xiàn)方法
這篇文章主要介紹了Android App更改應(yīng)用的圖標(biāo)的實現(xiàn)方法的相關(guān)資料,主要是通過入口Activity android:icon="@drawable/new_app_icon" 指向新的應(yīng)用圖標(biāo),需要的朋友可以參考下2017-08-08