androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.67k stars 399 forks source link

Allow adaptation between MediaCodec and bundled software codec #317

Open liuguangsen opened 1 year ago

liuguangsen commented 1 year ago

I used exoPlayer (with ffmpeg extension open) to play a link to my m3u8 like this . I found that ExoPlayer always uses FfmpegAudioDecoder and cannot switch to MediaCodecAudioRenderer?

EXTM3U

EXT-X-VERSION:7

EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="mp4a.40.34"

000_00000.m3u8

EXT-X-STREAM-INF:BANDWIDTH=320000,CODECS="mp4a.40.34"

001_00000.m3u8

EXT-X-STREAM-INF:BANDWIDTH=999000,CODECS="mp4a.40.34"

002_00000.m3u8

EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="flac"

003_00000.m3u8

christosts commented 1 year ago

Just for clarity, can you specify

liuguangsen commented 1 year ago
  1. which version of the library you are using?

ExoPlayer version is 2.18.1

  1. how you configure DefaultRenderersFactory

    public class AppRenderersFactory extends DefaultRenderersFactory {
     public AppRenderersFactory(Context context) {
        super(context);
        setExtensionRendererMode(EXTENSION_RENDERER_MODE_PREFER);
    }
    
    @Override
    protected void buildAudioRenderers(Context context, int extensionRendererMode, MediaCodecSelector mediaCodecSelector, boolean enableDecoderFallback, AudioSink audioSink, Handler eventHandler, AudioRendererEventListener eventListener, ArrayList<Renderer> out) {
        out.add(new FfmpegAudioRenderer());
        super.buildAudioRenderers(context, extensionRendererMode, mediaCodecSelector, enableDecoderFallback, audioSink, eventHandler, eventListener, out);
    }
    }
  2. whether the ffmpeg extension is configured to support AAC or only FLAC My Ffmpeg just support FLAC

Maybe my question is that First my ffmpegAudioRenderer just support FLAC.,but no AC4 and AAC. My m3u8 file like this.

#EXTM3U
#EXT-X-VERSION:7
#EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS="mp4a.40.34"
000_00000.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=320000,CODECS="mp4a.40.34"
001_00000.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=999000,CODECS="mp4a.40.34"
002_00000.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="flac"
003_00000.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="ac-4.02.02.00"
004_00000.m3u8

When ExoPlayer plays hls (m3u8), I choose to switch between trackIndex 4 (ac4 code) and trackIndex 3 (flac code). How does ExoPlayer switch between FfmpegAudioRenderer and MediaCodecAudioRenderer? Or switch back between trackIndex 3 (flac code) and trackIndex 4 (ac4 code) . Perhaps after the creation of ExoPlayer, does the player support dynamic switching of Renderers ? Now i just recreate ExoPlayer when i I choose to switch between trackIndex 4 (ac4 code) and trackIndex 3 (flac code). This method can work very well.
Can I achieve this sound quality switching function (switch between trackIndex 4 (ac4 code) and trackIndex 3 (flac code)) without recreating the player ?

christosts commented 1 year ago

@tonihei can you help on this issue?

tonihei commented 1 year ago

does the player support dynamic switching of Renderers

Not at the moment I'm afraid. ExoPlayer will create a group of tracks of all your variants and then tries to find the most suitable renderer for the entire group. In your case, this doesn't work very well because it can just assign it to a single renderer and depending on which one it chooses it can only play the tracks supported by this renderer. We can leave this issue open as an enhancement to track dynamic switching between MediaCodec and other software codecs.

Can I achieve this sound quality switching function

The only thing you can easily do right now is to use EXTENSION_RENDERER_MODE_PREFER is you prefer the FLAC track or EXTENSION_RENDERER_MODE_ON to prefer the MediaCodec-compatible tracks. (This effectively changes the order of renderers and then the mapping of the group to renderer is done differently).

It's theoretically possible to change the renderer association mid-playback, but you'd need to make customizations to MappingTrackSelector (and fork DefaultTrackSelector to inherit your changed class). This is very advanced and given how complicated both classes are, I'd not advise to do this.

liuguangsen commented 1 year ago

We can leave this issue open as an enhancement to track dynamic switching between MediaCodec and other software codecs.

ok ,that is very good idea ,thanks.

make customizations to MappingTrackSelector (and fork DefaultTrackSelector to inherit your changed class)

Then I'm trying to do this ,thank you for your suggestion.