package com.suno.android.media.hooks import android.content.Context import androidx.annotation.OptIn import androidx.media3.common.util.UnstableApi import androidx.media3.datasource.cache.CacheDataSource import androidx.media3.exoplayer.DefaultLoadControl import androidx.media3.exoplayer.DefaultRenderersFactory import androidx.media3.exoplayer.source.DefaultMediaSourceFactory import androidx.media3.exoplayer.source.preload.DefaultPreloadManager import com.suno.android.common_core_utils.SunoLogger import com.suno.android.media.CoreMediaPlayback import com.suno.android.media.HookClipPlayer import com.suno.android.media.HooksFeed import com.suno.android.media.hooks.preload.HooksFeedPreloadStatusControl import com.suno.android.media.player.HooksFeedPlaybackPlayerFactory import com.suno.android.media.player.PlayerFactory import com.suno.android.media.player.SharedPlayer import com.suno.android.media.player.pool.PlayerPool import com.suno.android.media.player.pool.PlayerPoolImpl import com.suno.android.media.player.pool.PlayerSlot import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import javax.inject.Singleton private const val HOOKS_FEED_MIN_BUFFER_MS = 5_000 private const val HOOKS_FEED_MAX_BUFFER_MS = 5_000 private const val HOOKS_FEED_BUFFER_FOR_PLAYBACK_MS = 500 private const val HOOKS_FEED_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = 500 @Module @InstallIn(SingletonComponent::class) interface HooksMediaModule { @Binds @Singleton @HooksFeed fun bindHooksFeedPlaybackPlayerFactory( impl: HooksFeedPlaybackPlayerFactory, ): PlayerFactory companion object { @OptIn(UnstableApi::class) @Provides @Singleton @HooksFeed fun provideHooksFeedPlayerPool( loggerFactory: SunoLogger.Factory, playerSlotFactory: PlayerSlot.Factory, @HooksFeed playerFactory: PlayerFactory, ): PlayerPool = PlayerPoolImpl( loggerFactory = loggerFactory, playerSlotFactory = playerSlotFactory, playerFactory = playerFactory, ) @Provides @Singleton @HookClipPlayer fun provideHookClipSharedPlayer( loggerFactory: SunoLogger.Factory, @CoreMediaPlayback playerFactory: PlayerFactory, ): SharedPlayer = SharedPlayer( loggerFactory = loggerFactory, playerFactory = playerFactory, ) @OptIn(UnstableApi::class) @Provides @Singleton @HooksFeed fun provideHooksFeedPreloadManagerBuilder( @ApplicationContext context: Context, hooksFeedPreloadStatusControl: HooksFeedPreloadStatusControl, @CoreMediaPlayback mediaPlaybackExoCacheDataSourceFactory: CacheDataSource.Factory, ): DefaultPreloadManager.Builder = DefaultPreloadManager.Builder(context, hooksFeedPreloadStatusControl) .setMediaSourceFactory( DefaultMediaSourceFactory(context) .setDataSourceFactory(mediaPlaybackExoCacheDataSourceFactory), ) .setRenderersFactory( DefaultRenderersFactory(context) .setEnableDecoderFallback(true), ) .setLoadControl( DefaultLoadControl.Builder() .setBufferDurationsMs( HOOKS_FEED_MIN_BUFFER_MS, HOOKS_FEED_MAX_BUFFER_MS, HOOKS_FEED_BUFFER_FOR_PLAYBACK_MS, HOOKS_FEED_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS, ) .build(), ) } }