Serie de desarrollo de audio y video de Android: uso de VideoView

¡Acostúmbrate a escribir juntos! Este es el cuarto día de mi participación en el "Nuevo plan diario de los Nuggets·Desafío de actualización de abril", haz clic para ver los detalles del evento .

Introducción a VideoView

Previamente introduje el uso de MediaPlayer+ SurfaceViewpara realizar la función de reproducción de video. Accidentalmente descubrí que los VideoViewcomponentes oficiales empaquetados para realizar la función de reproducción de video simple, y el formulario MediaPlayer+ SurfaceViewtambién se usa para controlar MediaPlayerla reproducción de archivos de video. El escenario de uso es relativamente simple y es adecuado para el escenario de solo reproducir el video. Su capacidad limitada no es adecuada para otras funciones, como ajustar el brillo del video.

MediaController

Además del componente de reproducción VideoView, también hay un MediaControllercomponente que proporciona una función de barra de operación de reproducción para reproducción de video, que admite reproducción de video, pausa, avance rápido, retroceso rápido y otras funciones. Además, también proporciona una función de barra de progreso que se puede arrastrar a una posición específica para reproducir el video.

usar

VideoViewEl paquete MediaPlayertambién proporciona una MediaPlayerAPI similar. Por ejemplo start, el método también tiene la función de reproducir video, pero es mejor configurar el setOnpreparedListenerresultado de la devolución de llamada antes de llamar al método para ejecutar el método, y el método setVideoPathse ejecutará activamente después de prepareAsyncque se llame al método. Ayuda a los desarrolladores a encapsular e implementar muchas funciones internamente. De VideoViewhecho, también puede aprender de su código fuente interno para crear un reproductor propio más amplio y completo.

API comunes ilustrar
establecer ruta de video Configurar recursos de video
comienzo jugar
pausa pausa
resumir repetición
tratar de Juega en una ubicación específica
está jugando Si el video se está reproduciendo
obtenerPosiciónActual Obtener la posición de reproducción actual
establecerMediaController Configurar MediaController
setOnpreparedListener Escuche el evento de finalización de carga de video
// 实例化videoView     
videoView = new VideoView(this);
Uri uri = Uri.fromFile(new File("sdcard/DCIM","新世纪福音战士24.mp4"));
//加载视频资源
videoView.setVideoURI(uri);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.addView(videoView);
setContentView(linearLayout);
//设置监听
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //回调成功并播放视频
        videoView.start();
    }
});
//创建操作栏
MediaController mediaController = new MediaController(this);
videoView.setMediaController(mediaController);
mediaController.setMediaPlayer(videoView);
复制代码

a5a4ba6ebe7731127c5f2f64eb01b134.jpg

Análisis de código fuente

VideoViewAhora que los dos componentes están encapsulados MediaController, muchas funciones que se han intentado implementar antes se encuentran en el proceso de uso para ver cómo se implementan.

pantalla de progreso

MediaControllershowSe puede ver un post(mShowProgress);método dentro del método de llamada cuando se muestra

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);
    }
}
复制代码

Se puede ver que mShowProgresses uno Runnable, y el retardo interno se llamará a sí mismo para actualizar setProgress(). setProgress()El método consiste en leer el MediaPlayerprogreso de la reproducción para actualizar la información de reproducción.

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

Adaptación al tamaño del juego

Antes de personalizar la adaptación del tamaño de la reproducción, VideoViewayuda directamente a los desarrolladores a lograr la adaptación de la reproducción de video internamente. El código detallado se puede reescribir onMeasuredirectamente . El algoritmo aproximado del código consiste VideoViewen reescribir el ancho y el alto calculados comparando el ancho y el alto del diseño y el ancho y el alto del video 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);
}
复制代码

Supongo que te gusta

Origin juejin.im/post/7085243234523283464
Recomendado
Clasificación