Android中VideoView音視頻開(kāi)發(fā)的實(shí)現(xiàn)
本篇文章主要介紹下Android 中的VideoView.
1: VideoView簡(jiǎn)介
VideoView是一個(gè)用于播放視頻的視圖組件,可以方便地在應(yīng)用程序中播放本地或網(wǎng)絡(luò)上的視頻文件。
VideoView可以直接在布局文件中使用,也可以在代碼中動(dòng)態(tài)創(chuàng)建。
它封裝了MediaPlayer和SurfaceView,提供了簡(jiǎn)單的接口來(lái)控制視頻的播放和顯示。
它提供了一系列方法來(lái)控制視頻的播放、暫停、停止等操作,并且支持全屏播放和視頻控制器的顯示。
VideoView播放視頻非常簡(jiǎn)單,只需要指定視頻的URL或本地路徑.
2: 使用
以下是VideoView的簡(jiǎn)單使用:
2.1 布局
在XML布局文件中添加VideoView組件.
<VideoView android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" android:id="@+id/videoview" />
2.2 設(shè)置視頻源
代碼如下:
videoView = findViewById(R.id.videoview); videoView.setVideoPath("sdcard/test.mp4");
除了setVideoPath外,我們還可以調(diào)用:
- setVideoURI(Uri uri)
- setVideoURI(Uri uri, Map<String, String> headers)
當(dāng)然不管是setVideoPath或者setVideoURI實(shí)際都是執(zhí)行的setVideoURI(Uri uri, Map<String, String> headers).
源碼如下:
/** * Sets video path. * * @param path the path of the video. */ public void setVideoPath(String path) { setVideoURI(Uri.parse(path)); } /** * Sets video URI. * * @param uri the URI of the video. */ public void setVideoURI(Uri uri) { setVideoURI(uri, null); }
2.3 播放視頻
videoView.start();
我們可以看下start()的源碼:
@Override public void start() { if (isInPlaybackState()) { mMediaPlayer.start(); mCurrentState = STATE_PLAYING; } mTargetState = STATE_PLAYING; }
可以看到實(shí)際上調(diào)用mMediaPlayer.start();另外設(shè)置了當(dāng)前的狀態(tài)為STATE_PLAYING.
這里直接調(diào)用了mMediaPlayer.start();那mMediaPlayer是什么時(shí)機(jī)初始化的呢?
查看源碼可以看到:
private void openVideo() { if (mUri == null || mSurfaceHolder == null) { // not ready for playback just yet, will try again later return; } // we shouldn't clear the target state, because somebody might have // called start() previously release(false); if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) { // TODO this should have a focus listener mAudioManager.requestAudioFocus(null, mAudioAttributes, mAudioFocusType, 0 /*flags*/); } try { mMediaPlayer = new MediaPlayer(); // TODO: create SubtitleController in MediaPlayer, but we need // a context for the subtitle renderers final Context context = getContext(); final SubtitleController controller = new SubtitleController( context, mMediaPlayer.getMediaTimeProvider(), mMediaPlayer); controller.registerRenderer(new WebVttRenderer(context)); controller.registerRenderer(new TtmlRenderer(context)); controller.registerRenderer(new Cea708CaptionRenderer(context)); controller.registerRenderer(new ClosedCaptionRenderer(context)); mMediaPlayer.setSubtitleAnchor(controller, this); if (mAudioSession != 0) { mMediaPlayer.setAudioSessionId(mAudioSession); } else { mAudioSession = mMediaPlayer.getAudioSessionId(); } mMediaPlayer.setOnPreparedListener(mPreparedListener); mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener); mMediaPlayer.setOnCompletionListener(mCompletionListener); mMediaPlayer.setOnErrorListener(mErrorListener); mMediaPlayer.setOnInfoListener(mInfoListener); mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); mCurrentBufferPercentage = 0; mMediaPlayer.setDataSource(mContext, mUri, mHeaders); mMediaPlayer.setDisplay(mSurfaceHolder); mMediaPlayer.setAudioAttributes(mAudioAttributes); mMediaPlayer.setScreenOnWhilePlaying(true); mMediaPlayer.prepareAsync(); for (Pair<InputStream, MediaFormat> pending: mPendingSubtitleTracks) { try { mMediaPlayer.addSubtitleSource(pending.first, pending.second); } catch (IllegalStateException e) { mInfoListener.onInfo( mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0); } } // we don't set the target state here either, but preserve the // target state that was there before. mCurrentState = STATE_PREPARING; attachMediaController(); } catch (IOException ex) { Log.w(TAG, "Unable to open content: " + mUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0); return; } catch (IllegalArgumentException ex) { Log.w(TAG, "Unable to open content: " + mUri, ex); mCurrentState = STATE_ERROR; mTargetState = STATE_ERROR; mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0); return; } finally { mPendingSubtitleTracks.clear(); } }
可以看到openVideo()
- release()方法釋放正在播放的視頻.
- 初始化mMediaPlayer,傳入U(xiǎn)ri,設(shè)置狀態(tài) STATE_PREPARING。
- attachMediaController()綁定MediaPlayer與VideoView。
最后openVideo()則是在setVideoURI(Uri uri, Map<String, String> headers)內(nèi)調(diào)用。
這樣其實(shí)已經(jīng)可以播放指定的視頻了。
下面的方法可選。
2.4 MediaController控制器
MediaController是一個(gè)用于控制媒體播放器的視圖組件。
MediaController的使用步驟如下:
- 創(chuàng)建一個(gè)MediaController對(duì)象:MediaController mediaController = new MediaController(context);
- 將MediaController與媒體播放器組件關(guān)聯(lián):mediaController.setMediaPlayer(mediaPlayer);
- 將MediaController添加到布局中:layout.addView(mediaController);
videoView.setMediaController(new MediaController(this)); videoView.start().
直接調(diào)用setMediaController,運(yùn)行后我們可以看到與之前直接調(diào)用start()的區(qū)別就是多了個(gè)控制器的顯示。其中包含一組常用的媒體控制按鈕,如播放/暫停、快進(jìn)/快退、前進(jìn)/后退等,并且可以與MediaPlayer或VideoView等媒體播放器組件進(jìn)行關(guān)聯(lián).
我們可以看下源碼:
public void setMediaController(MediaController controller) { if (mMediaController != null) { mMediaController.hide(); } mMediaController = controller; attachMediaController(); }
可以看到做的操作如下:
- 如果存在mMediaController,則調(diào)用hide方法。
- 對(duì)mMediaController賦值
- attachMediaController
到此這篇關(guān)于Android中VideoView音視頻開(kāi)發(fā)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Android VideoView音視頻內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Android UniversalVideoView實(shí)現(xiàn)視頻播放器
- Android音視頻開(kāi)發(fā)之VideoView使用指南
- Android自定義videoview仿抖音界面
- Android原生視頻播放VideoView的使用
- android多媒體類VideoView使用方法詳解
- Android編程實(shí)現(xiàn)VideoView循環(huán)播放功能的方法
- Android多媒體之VideoView視頻播放器
- Android VideoView類實(shí)例講解
- Android使用VideoView播放本地視頻和網(wǎng)絡(luò)視頻的方法
- android使用videoview播放視頻
相關(guān)文章
關(guān)于Android Studio安裝完后activity_main.xml前幾行報(bào)錯(cuò)的解決建議
這篇文章主要介紹了關(guān)于Android Studio安裝完后activity_main.xml前幾行報(bào)錯(cuò)的解決建議,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03Android中Activity常用功能設(shè)置小結(jié)(包括全屏、橫豎屏等)
這篇文章主要介紹了Android中Activity常用功能設(shè)置小結(jié)(包括全屏、橫豎屏等),以簡(jiǎn)單實(shí)例形式分析了Android實(shí)現(xiàn)全屏、豎屏及一直顯示等的技巧與注意事項(xiàng),需要的朋友可以參考下2015-10-10使用Chrome瀏覽器調(diào)試Android App詳解
這篇文章主要介紹了使用Chrome瀏覽器調(diào)試Android App詳解,本網(wǎng)講解了使用Facebook開(kāi)源Stetho實(shí)現(xiàn)在Chrome中調(diào)試Android App中,需要的朋友可以參考下2015-05-05Android中Webview打開(kāi)網(wǎng)頁(yè)的同時(shí)發(fā)送HTTP頭信息方法
這篇文章主要介紹了Android中Webview打開(kāi)網(wǎng)頁(yè)的同時(shí)發(fā)送HTTP頭信息方法,本文是講解的是一種通過(guò)修改Referer來(lái)控制盜鏈的方法,需要的朋友可以參考下2015-01-01Android 中 requestWindowFeature()的應(yīng)用
本文主要介紹 Android requestWindowFeature()方法,這里對(duì) requestWindowFeature()方法進(jìn)行詳解,對(duì)應(yīng)用程序窗體顯示狀態(tài)的操作有進(jìn)一步了解,希望能幫助有需要的小伙伴2016-07-07Android手機(jī)通過(guò)藍(lán)牙連接佳博打印機(jī)的實(shí)例代碼
這篇文章主要介紹了Android手機(jī)通過(guò)藍(lán)牙連接佳博打印機(jī)的實(shí)例代碼,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11android手機(jī)獲取gps和基站的經(jīng)緯度地址實(shí)現(xiàn)代碼
android手機(jī)如何獲取gps和基站的經(jīng)緯度地址,疑問(wèn),于是網(wǎng)上搜集整理一些,拿出來(lái)和大家分享下,希望可以幫助你們2012-12-12Android實(shí)現(xiàn)九宮格橫向左右滑動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)九宮格橫向左右滑動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08