我应该如何为 exoplayer 创建一个包含视频和图像文件 URI 的 ConcatenatingMediaSource?

How should I create a ConcatenatingMediaSource containing URIs of video and image files for an exoplayer?

我创建了一个 concatenatingMediaSource,但它跳过了图像 uri。 我知道 exoplayer 不支持图像文件。当图像 uri 出现并将图像加载到图像视图中时,我试图暂停并隐藏 exoplayer。

 public void loadMediaSources(){
            MediaSource[] mediaSourcesToLoad = new MediaSource[stories.size()];
            for(int i=0;i<stories.size();i++){
                MediaSource mediaSource = new ExtractorMediaSource(Uri.parse(stories.get(i).getVideoUrl()),
                        dataSourceFactory, extractorsFactory, null, null);
                mediaSourcesToLoad[i] = mediaSource;
            }

            mediaSources = new ConcatenatingMediaSource(mediaSourcesToLoad);

   if(player!=null && mediaSources!=null){
            player.prepare(mediaSources);
        }
}

@Override
public void onPositionDiscontinuity() {
        exoPlayerView.setVisibility(View.VISIBLE);
        ivStory.setVisibility(View.VISIBLE);
        mPosition = player.getCurrentWindowIndex();
        Log.d("Position of Video", String.valueOf(mPosition));

        if(stories!=null && stories.size()>0 && stories.get(player.getCurrentWindowIndex()).getPhotoUrl()!=null){
            viewPhoto(stories.get(player.getCurrentWindowIndex()).getPhotoUrl());
        }
    }



private void viewPhoto(String url){

        Glide.with(this).load(url).listener(new RequestListener<String, GlideDrawable>() {
            @Override
            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                return false;
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                stopPlayingVideo();
                exoPlayerView.setVisibility(View.INVISIBLE);
                ivStory.setVisibility(View.VISIBLE);
                return false;
            }
        }).into(ivStory);

    }

目前 ExoPlayer 不提供任何内置的图像播放支持。 您可以生成 N 秒的单色视频(例如使用 ffmpeg),您可以播放这些视频作为图像轨道。

private MediaSource trackToMediaSource(@NonNull Track track) {
    MediaSource source;
    Uri trackUri;
    switch (track.getType()) {
        case VIDEO:
            trackUri = Uri.parse(track.getUrl());
            ...
            break;
        case IMAGE:
            // Currently images are not supported. We use hardcoded video URL as a workaround.
            trackUri = Uri.parse("asset:///blue.mp4");
            ...
            break;
        ...
    }
        ...
    return source;
}

FFmpeg 命令:

ffmpeg -f lavfi -i color=c=#10408c -t 5 blue.mp4

当播放器切换到图像轨道时显示 ImageView:

@Override
public void onPositionDiscontinuity() {
    int currentTrack = player.getCurrentWindowIndex();
    Track track = tracks.get(currentTrack);
    switch (track.getType()) {
        case IMAGE:
            showImageAbovePlayer(track.getUrl()); // blue.mp4 is played for 5 seconds under the image, but user sees only image
            break;
        case VIDEO:
            hideImageAbovePlayer(); // hide image, user sees current video track
            break;
    }
}