Skip to content

[ZH] 5.使用 ExoPlayer

jrfeng edited this page Jul 3, 2022 · 9 revisions

exo 模块提供了一个基于 ExoPlayerMusicPlayer 实现:ExoMusicPlayer

要使用 ExoMusicPlayer,需要开发者对 ExoPlayer 有一定的了解。

添加对 exo 模块的依赖:

提示exo 模块最低支持到 API 21,如果你需要支持到 API 16,请使用 exo-api16 模块代替它。

dependencies {
    // 最低支持到 API 21
    implementation 'com.github.jrfeng.snow:exo:1.2'

    // 如果你需要支持到 API 16,请使用 exo-api16 模块代替 exo 模块:
    // implementation 'com.github.jrfeng.snow:exo-api16:1.2'
}

开启 Java 8 支持:

android {
    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

ExoMusicPlayer 的构造方法:

public ExoMusicPlayer(@NonNull Context context, @NonNull Uri uri)

public ExoMusicPlayer(@NonNull Context context, @NonNull MediaItem mediaItem)

public ExoMusicPlayer(@NonNull Context context, @NonNull MediaSourceFactory mediaSourceFactory, @NonNull Uri uri)

注意!exo 模块仅添加了对 ExoPlayerexoplayer-core, extension-okhttp 模块的依赖,如您需要使用 ExoPlayer 的其他功能,需要自行添加对应模块的依赖,具体请参考 ExoPlayer 官方文档

应用 ExoMusicPlayer

需要通过继承 PlayerService 并覆盖其 onCreateMusicPlayer(Context, MusicItem, Uri) 方法来应用自定义 MusicPlayer

例:

@PersistenId("MyPlayerService")
public MyPlayerService extends PlayerService {
    ...

    @NonNull
    @Override
    protected MusicPlayer onCreateMusicPlayer(@NonNull Context context, @NonNull MusicItem musicItem, @NonNull Uri uri) {
        return new ExoMusicPlayer(context, uri);
    }
}

更多内容,请查看:自定义 PlayerService

常见问题

HTTP 302 错误

默认情况下,ExoPlayer 不允许跨协议重定向,例如 http -> https 或者 https -> http

如果你需要启用跨协议重定向,可以参照以下代码:

DefaultHttpDataSourceFactory httpDataSourceFactory =
                new DefaultHttpDataSourceFactory(
                        Util.getUserAgent(context, context.getPackageName()),
                        null,
                        DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
                        DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
                        true/*允许跨协议重定向*/);

DefaultDataSourceFactory dataSourceFactory = 
                new DefaultDataSourceFactory(context, httpDataSourceFactory);

HTTPS 握手失败

这是因为 API level 20 以下的 Android 版本默认没有启用 TLS v1.2。解决方案请参考:https://github.com/square/okhttp/issues/2372#issuecomment-244807676

本项目基于以上解决方案在 exo 模块中提供了一个工具类:OkHttpUtil

只需将你的 OkHttpClient.Builder 对象传递给静态方法 OkHttpUtil.enableTls12OnPreLollipop(OkHttpClient.Builder builder) 即可。

例:

OkHttpClient.Builder builder = new OkHttpClient.Builder();

OkHttpUtil.enableTls12OnPreLollipop(builder);

End