2

在这个项目中有一个“SimpleExoPlayer”,播放器的版本是“exoplayer:r2.5.3”。运行应用程序“SimpleExoPlayer”后缓冲视频内容并流畅播放。但是用户将“SeekBar”设置为之前的位置,“SimpleExoPlayer”重新缓冲以显示视频。对于大文件大小的“.mp4”视频来说,这是一个耗时的过程。感谢您帮助解决此问题。

下面是我的代码。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:padding="10dp">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:orientation="vertical">

                <com.google.android.exoplayer2.ui.SimpleExoPlayerView
                    android:id="@+id/simple_expo_player"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">


                </com.google.android.exoplayer2.ui.SimpleExoPlayerView>


            </LinearLayout>


        </LinearLayout>

    </ScrollView>


</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private SimpleExoPlayerView simpleExoPlayerView;

    SimpleExoPlayer player;

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

        initUi();
    }

    public void initUi(){

// 1. Create a default TrackSelector
        BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

// 2. Create the player

        player = ExoPlayerFactory.newSimpleInstance(getApplicationContext(), trackSelector);


// 3. Produces DataSource instances through which media data is loaded.
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(), Util.getUserAgent(getApplicationContext(), "com.a3iteam.exoplayertest"));

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

// 5. This is the MediaSource representing the media to be played.

        MediaSource videoSource = new ExtractorMediaSource(Uri.parse("https://www.w3schools.com/html/mov_bbb.mp4"),dataSourceFactory, extractorsFactory, null, null);


// 6. Prepare the player with the source.

        simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.simple_expo_player);

        simpleExoPlayerView.setPlayer(player);


    }


}
4

2 回答 2

2

当用户向后搜索时,没有什么可以阻止播放器缓冲。过去的数据在播放后会被丢弃,您无法轻易更改此行为。

向后搜索时,有一些选项可以最大限度地减少延迟:

1. 确保您的服务器支持范围请求

在提供视频文件时,IMO 必须支持范围请求,不仅是向后搜索,而且是一般搜索。

对于大文件大小的“.mp4”视频来说,这是一个耗时的过程。

mp4 文件的大小不应影响向后搜索时的延迟。您对“大文件大小”的概念使我认为您的服务器可能不支持http 范围请求。不过我可能是错的。只想确认一下。:)

你可以像这样检查:

卷曲-I http://i.imgur.com/z4d4kWk.jpg

HTTP/1.1 200 OK ...接受范围:字节

如果您看到“Accept-Ranges: bytes”标头,则支持范围请求。

2.使用缓存

ExoPlayer 库带有一个CacheDataSource和一个相应的CacheDataSourceFactory。因此,您可以通过包装数据源工厂轻松缓存下载的内容:

DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
    getApplicationContext(), Util.getUserAgent(getApplicationContext(),
    "com.a3iteam.exoplayertest"));
Cache cache = new SimpleCache(cacheDir, 
    new LeastRecentlyUsedCacheEvictor(maxBytes));
dataSourceFactory = new CacheDataSourceFactory(cache,
    dataSourceFactory);

当用户向后搜索时,媒体从本地磁盘加载而不是下载,这减少了延迟。不确定您是否要为向后搜索用例通常缓存所有内容。也许将其限制在移动网络。在带有 http 范围请求的 wifi 缓冲应该足够好。

无论哪种方式:尽快删除缓存的数据。

于 2017-10-29T23:01:30.413 回答
0

我发现了一些关于这种缓存机制的东西。看起来如果你直到视频结束才搜索,缓存就会完成。否则它会再次缓存。我已经通过完全切断手机和模拟器上的互联网来验证这一点。它工作得很好,我能够在没有互联网连接的情况下在视频中的任何地方寻找。关键是等待整个视频完成后再搜索。你可以尝试下面的代码来创建一个带有缓存的 exoplayer。

private void prepare_player()
{
    File downloadDirectory = context.getExternalFilesDir(null);
    downloadDirectory = context.getFilesDir();
    SimpleCache simple_cache = new SimpleCache(downloadDirectory, new NoOpCacheEvictor(), new ExoDatabaseProvider(getApplicationContext()));
    MediaItem media_item = MediaItem.fromUri(video_uri);
    CacheDataSource.Factory cache_datasource_factory = new CacheDataSource.Factory().setCache(simple_cache).setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory().setUserAgent("<your_app>"));
    MediaSource media_source = new ProgressiveMediaSource.Factory(cache_datasource_factory).createMediaSource(media_item);
    exo_player = new SimpleExoPlayer.Builder(this).build();
    exo_player.setMediaSource(media_source);
    exo_player.setPlayWhenReady(true);
    exo_player.prepare();
    player_view.setPlayer(exo_player);
}
于 2021-09-09T07:56:31.220 回答