【重生之我在学Android原生】Media3

相关文章

【重生之我在学Android原生】ContentProvider(Java)
【重生之我在学Android原生】Media3

前言

内容颇多,尽量从简

ExoPlayer使用

官方文档
参考文章

实现效果

Android(java)
使用ExoPlayer播放视频,自定义ExoPlayer界面,记录播放位置(横屏竖屏切换/切换至后台等)

案例实现

创建项目

在这里插入图片描述
在这里插入图片描述

添加依赖

在这里插入图片描述
Sync 一下

/// Jetpack Media3 ExoPlayer
    implementation ("androidx.media3:media3-exoplayer:1.3.1")
    implementation ("androidx.media3:media3-ui:1.3.1")
    implementation ("androidx.media3:media3-common:1.3.1")

转到activity_main.xml

在这里插入图片描述
选择Player.View

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.media3.ui.PlayerView
        android:id="@+id/video_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

player初始化

要在Activity的生命周期中完成player的初始化销毁等
在这里插入图片描述
在这里插入图片描述

package com.test.exoplayerexampleapplication;

import androidx.annotation.OptIn;
import androidx.appcompat.app.AppCompatActivity;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.ui.PlayerView;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @OptIn(markerClass = UnstableApi.class) @Override
    protected void onStart() {
   
        super.onStart();
        if (Util.SDK_INT >= 24) {
   
            initializePlayer();
        }
    }

    @OptIn(markerClass = UnstableApi.class) @Override
    protected void onResume() {
   
        super.onResume();
        if (Util.SDK_INT < 24) {
   
            initializePlayer();
        }
    }

    private void initializePlayer() {
   }
}

定义PlayerView,ExoPlayer

    private PlayerView playerView;
    private ExoPlayer exoPlayer;
    private final Uri videoOneUri = Uri.parse("http://www.w3school.com.cn/example/html5/mov_bbb.mp4");

在AndroidManifest.xml中定义网络权限,如果链接是Http,还需加userCleartextTraffic
在这里插入图片描述

<uses-permission android:name="android.permission.INTERNET" />
android:usesCleartextTraffic="true"

定义initializePlayer()方法

private void initializePlayer() {
   
        playerView = findViewById(R.id.video_view);
        exoPlayer = new ExoPlayer.Builder(this).build();
        playerView.setPlayer(exoPlayer);
        MediaItem mediaItem = MediaItem.fromUri(videoOneUri);
        exoPlayer.addMediaItem(mediaItem);
        exoPlayer.prepare();
    }

运行可以播放视频
在这里插入图片描述

释放资源

媒体播放器是很占用资源的,所以当不再需要播放器时,要释放它,当然也要在Activity的生命周期中释放资源
在这里插入图片描述
在onStop和onPause适当调用
在这里插入图片描述

    @OptIn(markerClass = UnstableApi.class) @Override
    protected void onPause() {
   
        super.onPause();
        if (Util.SDK_INT < 24) {
   
            releasePlayer();
        }
    }

    @OptIn(markerClass = UnstableApi.class) @Override
    protected void onStop() {
   
        super.onStop();
        if (Util.SDK_INT >= 24) {
   
            releasePlayer();
        }
    }

    private void releasePlayer() {
   
        exoPlayer.release();
    }

记录视频的播放状态

重新运行项目,测试切换至后台
在这里插入图片描述
切换至后台的生命周期,可以知道当APP放到后台,会调用player.release()方法释放
在这里插入图片描述
我们发现视频切换到后台,再切换回来,之前的播放到第四秒,切换回来发现,又回到第0秒。所以,现在需要记录之前播放的位置,播放的状态,播放到第几个视频了。
既然没有onDestory掉Activity
那么定义三个变量(播放位置,播放状态,第几个视频)

    private Long playbackPosition = 0L;
    private int currentMediaItemIndex = 0;
    private boolean playWhenReady = false;

在这里插入图片描述

playbackPosition = exoPlayer.getCurrentPosition();
        currentMediaItemIndex = exoPlayer.getCurrentMediaItemIndex();
        playWhenReady = exoPlayer.getPlayWhenReady();
exoPlayer.setPlayWhenReady(playWhenReady);
        exoPlayer.seekTo(currentMediaItemIndex, playbackPosition);

添加新的视频链接

private final Uri videoTwoUri = Uri.parse("https://media.w3.org/2010/05/sintel/trailer.mp4");

在这里插入图片描述
运行测试,播放下一个视频,并播放至一半,切换到后台,再切换回来
在这里插入图片描述

横竖屏切换

在这里插入图片描述
横竖屏切换的生命周期,Activity被Destory了
在这里插入图片描述

使用SharedPreference来存储键值对,参考官方文档,官方推荐用DataStore
在这里插入图片描述
那使用DataStore
在这里插入图片描述
我们现在做的事情是,使用DataStore Preference来存储视频在释放之前的播放进度,播放状态,播放到第几个视频了。
按照官网配置Preferences DataStore
引入依赖
在这里插入图片描述

/// Preferences DataStore
    implementation("androidx.datastore:datastore-preferences:1.0.0")
    /// RxJava2 support
    implementation("androidx.datastore:datastore-preferences-rxjava2:1.0.0")
    /// RxJava3 support
    implementation("androidx.datastore:datastore-preferences-rxjava3:1.0.0")

实例RxDataStore,销毁

private RxDataStore<Preferences> dataStore;
if (dataStore == null) {
   
            dataStore = new RxPreferenceDataStoreBuilder(this, "ExoPlayerKeys").build();
        }
    @Override
    protected void onDestroy() {
   
        super.onDestroy();
        if (dataStore != null) {
   
            dataStore.dispose();
        }
    }

在这里插入图片描述
在这里插入图片描述
定义三个Key

    Preferences.Key<Integer> currentMediaItemIndexPK;
    Preferences.Key<Integer> playbackPositionPK;
    Preferences.Key<Boolean> playWhenReadyPK;
currentMediaItemIndexPK = PreferencesKeys.intKey("currentMediaItemIndex");
        playbackPositionPK = PreferencesKeys.intKey("playbackPosition");
        playWhenReadyPK = PreferencesKeys.booleanKey("playWhenReady");

在这里插入图片描述
使用PreferencesKeys存储值
在这里插入图片描述

private void saveVideoRecord() {
   
        dataStore.updateDataAsync(preferences -> {
   
            MutablePreferences mutablePreferences = preferences.toMutablePreferences();
            mutablePreferences.set(currentMediaItemIndexPK, currentMediaItemIndex);
            mutablePreferences.set(playbackPositionPK, playbackPosition.intValue());
            mutablePreferences.set(playWhenReadyPK, playWhenReady);
            return Single.
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sheng_er_sheng

打赏是什么?好吃么

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值