android ExoPlayer 2-如何使HTTP 301重定向工作?

xpcnnkqh  于 2022-12-09  发布在  Android
关注(0)|答案(4)|浏览(307)

我开始使用ExoPlayer来播放一些音频。一切都很好,直到我遇到一个有“301永久移动”重定向的URL。ExoPlayer2默认情况下不处理这个问题。
我已经看过这个帖子了:https://github.com/google/ExoPlayer/issues/423
他们说要在HttpDataSource或UriDataSource中添加新的“allowCrossDomainRedirects”标志。

//I am NOT using SimpleExoPlayer because I need a different renderer.
exoPlayer = ExoPlayerFactory.newInstance(renderers, trackSelector, loadControl);

final DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
            context,
            Util.getUserAgent(context, applicationInfo.getAppName())
);

// Produces Extractor instances for parsing the media data.
final ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

// This is the MediaSource representing the media to be played.
MediaSource mediaSource = new ExtractorMediaSource(
            Uri.parse(media.getUriString()) /* uri */,
            dataSourceFactory,
            extractorsFactory,
            10,
            null /* eventHandler */,
            null /* eventListener */);

exoPlayer.prepare(mediaSource);

看看ExtractorMediaSource是如何需要dataSourceFactory而不是DataSource的。事实上,我甚至在ExoPlayer2上找不到HttpDataSource和UriDataSource类。看起来它们已经被删除了。
所以我找不到一个方法来添加帖子上提到的旗帜。有人能帮助我吗?

voj3qocg

voj3qocg1#

问题中描述的问题是关于跨协议重定向(从http到https或反之亦然)。Exoplayer支持此功能,但您必须将allowCrossProtocolRedirects设置为true。默认情况下支持常规重定向(包括301重定向)。您收到的重定向很可能是跨协议重定向。
若要创建正在调用的数据源:

DefaultDataSourceFactory(Context context, String userAgent)

这个建构函式会建立将allowCrossProtocolRedirects设定为falseDefaultHttpDataSourceFactory
要更改此设置,您需要调用:

DefaultDataSourceFactory(Context context, TransferListener<? super DataSource> listener,
  DataSource.Factory baseDataSourceFactory)

并使用您自己的DefaultHttpDataSourceFactory,将allowCrossProtocolRedirects设置为true作为baseDataSourceFactory
例如:

String userAgent = Util.getUserAgent(context, applicationInfo.getAppName());

// Default parameters, except allowCrossProtocolRedirects is true
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
    userAgent,
    null /* listener */,
    DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
    DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
    true /* allowCrossProtocolRedirects */
);

DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
    context,
    null /* listener */,
    httpDataSourceFactory
);

如果需要更频繁地执行此操作,还可以创建一个helper方法:

public static DefaultDataSourceFactory createDataSourceFactory(Context context,
        String userAgent, TransferListener<? super DataSource> listener) {
    // Default parameters, except allowCrossProtocolRedirects is true
    DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
        userAgent,
        listener,
        DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
        DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
        true /* allowCrossProtocolRedirects */
    );

    DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
        context,
        listener,
        httpDataSourceFactory
    );

    return dataSourceFactory;
}

这将允许跨协议重定向。
旁注:“301永久移动”表示客户端需要更新他们的网址到新的。“302找到”是用于常规重定向。如果可能的话,更新返回“301永久移动”的网址。

2mbi3lxu

2mbi3lxu2#

它工作

val httpDataSourceFactory = DefaultHttpDataSourceFactory(Util.getUserAgent(context, "Player"),null,DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
        DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
        true)

val dataSourceFactory: DataSource.Factory = DefaultDataSourceFactory(context, null, httpDataSourceFactory)
bkhjykvo

bkhjykvo3#

试试这个:

// Build a HttpDataSource.Factory with cross-protocol redirects enabled.
HttpDataSource.Factory httpDataSourceFactory =
    new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);

// Wrap the HttpDataSource.Factory in a DefaultDataSource.Factory, which adds in
// support for requesting data from other sources (e.g., files, resources, etc).
DefaultDataSource.Factory dataSourceFactory =
    new DefaultDataSource.Factory(context, httpDataSourceFactory);

// Inject the DefaultDataSourceFactory when creating the player.
ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory))
        .build();

对我有用。

8aqjt8rx

8aqjt8rx4#

公认的答案看起来有点过时,因为DefaultHttpDataSource类已被弃用,我们假设将其替换为DefaultHttpDataSource.Factory,see the official documentation
所以与其

DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(
    userAgent,
    null /* listener */,
    DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
    DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
    true /* allowCrossProtocolRedirects */
);

我们本可以

final DefaultHttpDataSource.Factory defaultDataSourceFactory = new DefaultHttpDataSource
    .Factory()
    .setUserAgent(userAgent)
    .setTransferListener(listener)     
.setConnectTimeoutMs(DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS)
    .setReadTimeoutMs(DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS)
    .setAllowCrossProtocolRedirects(true);

也不要忘记使用如果你必须

final DefaultHttpDataSource defaultDataSource = defaultDataSourceFactory.createDataSource();

最后你猜怎么着:DefaultDataSourceFactory也已过时,我们应该改用DefaultDataSource.Factory。

相关问题