最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android音視頻開發(fā)之VideoView使用指南

 更新時(shí)間:2022年04月12日 09:08:26   作者:JulyYu  
VideoView組件內(nèi)部同樣是使用MediaPlayer+SurfaceView的形式控制MediaPlayer對(duì)視頻文件進(jìn)行播放,本文就來(lái)詳細(xì)講講它的使用方法,需要的可以參考一下

VideoView介紹

之前介紹過(guò)使用MediaPlayer+SurfaceView實(shí)現(xiàn)播放視頻功能。無(wú)意間發(fā)現(xiàn)官方封裝了VideoView組件來(lái)實(shí)現(xiàn)簡(jiǎn)單視頻播放功能,內(nèi)部同樣是使用MediaPlayer+SurfaceView的形式控制MediaPlayer對(duì)視頻文件進(jìn)行播放。使用場(chǎng)景比較簡(jiǎn)單,適用于只是播放視頻的場(chǎng)景,其提供能力有限不太適合使用在調(diào)節(jié)視頻亮度等其他功能。

MediaController

除了播放組件VideoView外還有MediaController組件為視頻播放提供播放操作欄功能,可支持視頻播放、暫停、快進(jìn)、快退等功能。另外還提供進(jìn)度條功能可以拖拽到指定位置進(jìn)行播放視頻。

使用

VideoView封裝了MediaPlayer同樣也提供了類似于MediaPlayer的api。例如start方法同樣是播放視頻功能,但調(diào)用該方法前最好也是通過(guò)設(shè)置setOnpreparedListener回調(diào)結(jié)果來(lái)執(zhí)行,當(dāng)調(diào)用setVideoPath后會(huì)主動(dòng)執(zhí)行prepareAsync方法。在VideoView內(nèi)部幫助開發(fā)者封裝實(shí)現(xiàn)了很多功能,其實(shí)也能借鑒其內(nèi)部源碼來(lái)實(shí)現(xiàn)功能更全面功能更完備的自制播放器。

常用Api說(shuō)明
setVideoPath設(shè)置視頻資源
start播放
pause暫停
resume重播
seekTo指定位置播放
isPlaying視頻是否播放
getCurrentPosition獲取當(dāng)前播放位置
setMediaController設(shè)置MediaController
setOnpreparedListener監(jiān)聽視頻裝載完成事件
// 實(shí)例化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);

源碼分析

既然封裝了VideoViewMediaController兩者組件,在使用過(guò)程中也發(fā)現(xiàn)了許多之前嘗試實(shí)現(xiàn)的一些功能看看他們又是如何實(shí)現(xiàn)的。

進(jìn)度顯示

MediaController顯示時(shí)調(diào)用show方法內(nèi)部可以看到一個(gè)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是一個(gè)Runnable,內(nèi)部會(huì)延遲不停調(diào)用自己來(lái)更新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));
        }
    }
};

播放尺寸適配

之前自定義實(shí)現(xiàn)播放尺寸適配,在VideoView內(nèi)部直接幫助開發(fā)者實(shí)現(xiàn)視頻播放適配,詳細(xì)代碼可以直接看onMeasure重寫。代碼大致算法就是通過(guò)比較VideoView布局寬高和視頻的寬高進(jìn)行比例比較來(lái)重寫計(jì)算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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    Android實(shí)現(xiàn)學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)學(xué)生管理系統(tǒng)的相關(guān)代碼,供大家學(xué)習(xí)借鑒,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Android下的POS打印機(jī)調(diào)用的簡(jiǎn)單實(shí)現(xiàn)

    Android下的POS打印機(jī)調(diào)用的簡(jiǎn)單實(shí)現(xiàn)

    本篇文章主要介紹了Android下的POS打印機(jī)調(diào)用的簡(jiǎn)單實(shí)現(xiàn),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-04-04
  • WindowsAndroid 安裝教程詳解

    WindowsAndroid 安裝教程詳解

    本文主要介紹 WindowsAndroid 的安裝,這里羅列了詳細(xì)的安裝步驟,有需要的小伙伴可以參考下
    2016-09-09
  • Android開發(fā)利器之pidcat安裝方式

    Android開發(fā)利器之pidcat安裝方式

    pidcat 是Android屆JakeWharton大神開發(fā)的一款命令行工具,堪稱Android開發(fā)利器,它能方便Android程序猿捕獲日志,過(guò)濾日志,定位程序問(wèn)題,超級(jí)好用。這篇文章給大家介紹了Android開發(fā)利器之pidcat,需要的朋友可以參考下
    2019-05-05
  • Android自定義控件之圓形、圓角ImageView

    Android自定義控件之圓形、圓角ImageView

    這篇文章主要為大家詳細(xì)介紹了Android自定義控件之圓形、圓角ImageView的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android ProductFlavor的使用詳解

    Android ProductFlavor的使用詳解

    如果你的項(xiàng)目需要要區(qū)分國(guó)內(nèi)版和國(guó)外版甚至還要根據(jù)用戶是否是VIP會(huì)員加上收費(fèi)和免費(fèi)的版本,我們可以使用ProductFlavor對(duì)UI布局和icon圖標(biāo)進(jìn)行版本區(qū)分,有此類需求的朋友,不妨了解下本文
    2021-06-06
  • 解決Android 10/Android Q手機(jī)在后臺(tái)無(wú)法正常定位問(wèn)題

    解決Android 10/Android Q手機(jī)在后臺(tái)無(wú)法正常定位問(wèn)題

    這篇文章主要介紹了解決Android 10/Android Q手機(jī)在后臺(tái)無(wú)法正常定位問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • android 開發(fā)中使用okhttp上傳文件到服務(wù)器

    android 開發(fā)中使用okhttp上傳文件到服務(wù)器

    在開發(fā)android手機(jī)客戶端,常常會(huì)需要上傳文件到服務(wù)器,使用okhttp會(huì)是一個(gè)很好的選擇,它使用很簡(jiǎn)單,而且運(yùn)行效率也很高,下面小編給大家?guī)?lái)了android 開發(fā)中使用okhttp上傳文件到服務(wù)器功能,一起看看吧
    2018-01-01
  • Android實(shí)現(xiàn)越界回彈效果

    Android實(shí)現(xiàn)越界回彈效果

    這篇文章主要介紹了Android實(shí)現(xiàn)越界回彈效果,支持水平和垂直方向,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android實(shí)現(xiàn)Back功能代碼片段總結(jié)

    Android實(shí)現(xiàn)Back功能代碼片段總結(jié)

    今天把在公司實(shí)現(xiàn)某功能所用到的Back鍵功能模塊代碼片段做一個(gè)整理。方便以后直接拿出來(lái)使用
    2014-09-09

最新評(píng)論

四川省| 高密市| 西畴县| 临猗县| 交口县| 合阳县| 淮滨县| 虞城县| 三江| 富宁县| 龙门县| 社旗县| 合川市| 高唐县| 宁蒗| 龙南县| 电白县| 通州区| 平邑县| 灵川县| 清涧县| 长顺县| 启东市| 安国市| 旬邑县| 周宁县| 嫩江县| 宽甸| 洛宁县| 柘荣县| 天水市| 尼玛县| 大同市| 闽侯县| 台山市| 顺义区| 进贤县| 景德镇市| 嵊泗县| 海淀区| 澄城县|