溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android音視頻開發(fā)中VideoView怎么使用

發(fā)布時間:2022-04-12 11:10:23 來源:億速云 閱讀:377 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“Android音視頻開發(fā)中VideoView怎么使用”,在日常操作中,相信很多人在Android音視頻開發(fā)中VideoView怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Android音視頻開發(fā)中VideoView怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

VideoView介紹

之前介紹過使用MediaPlayer+SurfaceView實現播放視頻功能。無意間發(fā)現官方封裝了VideoView組件來實現簡單視頻播放功能,內部同樣是使用MediaPlayer+SurfaceView的形式控制MediaPlayer對視頻文件進行播放。使用場景比較簡單,適用于只是播放視頻的場景,其提供能力有限不太適合使用在調節(jié)視頻亮度等其他功能。

MediaController

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

使用

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

常用Api說明
setVideoPath設置視頻資源
start播放
pause暫停
resume重播
seekTo指定位置播放
isPlaying視頻是否播放
getCurrentPosition獲取當前播放位置
setMediaController設置MediaController
setOnpreparedListener監(jiān)聽視頻裝載完成事件
// 實例化videoView     
videoView = new VideoView(this);
Uri uri = Uri.fromFile(new File("sdcard/DCIM","新世紀福音戰(zhàn)士24.mp4"));
//加載視頻資源
videoView.setVideoURI(uri);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.addView(videoView);
setContentView(linearLayout);
//設置監(jiān)聽
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //回調成功并播放視頻
        videoView.start();
    }
});
//創(chuàng)建操作欄
MediaController mediaController = new MediaController(this);
videoView.setMediaController(mediaController);
mediaController.setMediaPlayer(videoView);

Android音視頻開發(fā)中VideoView怎么使用

源碼分析

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

進度顯示

MediaController顯示時調用show方法內部可以看到一個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,內部會延遲不停調用自己來更新setProgress()。setProgress()方法就是讀取MediaPlayer播放進度從而更新播放信息。

private final Runnable mShowProgress = new Runnable() {
    @Override
    public void run() {
        int pos = setProgress();
        if (!mDragging && mShowing && mPlayer.isPlaying()) {
            postDelayed(mShowProgress, 1000 - (pos % 1000));
        }
    }
};

播放尺寸適配

之前自定義實現播放尺寸適配,在VideoView內部直接幫助開發(fā)者實現視頻播放適配,詳細代碼可以直接看onMeasure重寫。代碼大致算法就是通過比較VideoView布局寬高和視頻的寬高進行比例比較來重寫計算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);
}

到此,關于“Android音視頻開發(fā)中VideoView怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI