Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import io.github.peerless2012.ass.media.type.AssRenderType

class MainActivity : AppCompatActivity() {

private var url = "http://192.168.0.254:80/files/f.mp4"
private var url = "http://192.168.0.254:80/files/c.mkv"

private lateinit var player: ExoPlayer

Expand All @@ -48,7 +48,7 @@ class MainActivity : AppCompatActivity() {
player = ExoPlayer.Builder(this)
.buildWithAssSupport(
this,
AssRenderType.LEGACY
AssRenderType.CANVAS
)
playerView = findViewById(R.id.main_player)
playerView.player = player
Expand Down Expand Up @@ -77,7 +77,7 @@ class MainActivity : AppCompatActivity() {
val mediaItem = MediaItem.Builder()
.setUri(url)
.setSubtitleConfigurations(ImmutableList.of(enConfig, jpConfig, zhConfig))
player.setMediaItem(mediaItem.build())
player.setMediaItem(mediaItem.build(), 30*1000)
player.prepare()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ class AssHandler(val renderType: AssRenderType) : Listener {
var surfaceSize = Size.ZERO
private set

var videoTime = -1L
set(value) {
if (field == value) {
return
}
field = value
}

/** The overlay manager for toggling the effects renderer. */
private var overlayManager: AssOverlayManager? = null

Expand All @@ -70,7 +78,7 @@ class AssHandler(val renderType: AssRenderType) : Listener {
player.addListener(this)
handler = Handler(player.applicationLooper)
if (renderType != AssRenderType.LEGACY) {
overlayManager = AssOverlayManager(player, renderType == AssRenderType.OPEN_GL)
overlayManager = AssOverlayManager(this, player, renderType == AssRenderType.OPEN_GL)
}
}

Expand All @@ -85,6 +93,7 @@ class AssHandler(val renderType: AssRenderType) : Listener {
track = null
availableTracks.clear()
videoSize = Size.ZERO
videoTime = -1
overlayManager?.disable()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.github.peerless2012.ass.media.factory

import android.os.Handler
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.Renderer
import androidx.media3.exoplayer.RenderersFactory
import androidx.media3.exoplayer.audio.AudioRendererEventListener
import androidx.media3.exoplayer.metadata.MetadataOutput
import androidx.media3.exoplayer.text.TextOutput
import androidx.media3.exoplayer.video.VideoRendererEventListener
import io.github.peerless2012.ass.media.AssHandler
import io.github.peerless2012.ass.media.render.AssRenderer

/**
* @Author peerless2012
* @Email peerless2012@126.com
* @DateTime 5/25/25 10:47 PM
* @Version V1.0
* @Description
*/
@UnstableApi
class AssRenderersFactory(private val assHandler: AssHandler, private val renderersFactory: RenderersFactory): RenderersFactory {
override fun createRenderers(
eventHandler: Handler,
videoRendererEventListener: VideoRendererEventListener,
audioRendererEventListener: AudioRendererEventListener,
textRendererOutput: TextOutput,
metadataRendererOutput: MetadataOutput
): Array<Renderer> {
val renderers = renderersFactory.createRenderers(eventHandler, videoRendererEventListener, audioRendererEventListener, textRendererOutput, metadataRendererOutput)
return (renderers.toMutableList() + AssRenderer(assHandler)).toTypedArray()
}

override fun createSecondaryRenderer(
renderer: Renderer,
eventHandler: Handler,
videoRendererEventListener: VideoRendererEventListener,
audioRendererEventListener: AudioRendererEventListener,
textRendererOutput: TextOutput,
metadataRendererOutput: MetadataOutput
): Renderer? {
return renderersFactory.createSecondaryRenderer(
renderer,
eventHandler,
videoRendererEventListener,
audioRendererEventListener,
textRendererOutput,
metadataRendererOutput
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DataSource
import androidx.media3.datasource.DefaultDataSource
import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.RenderersFactory
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.extractor.DefaultExtractorsFactory
import androidx.media3.extractor.ExtractorsFactory
import androidx.media3.extractor.mkv.MatroskaExtractor
import io.github.peerless2012.ass.media.AssHandler
import io.github.peerless2012.ass.media.extractor.AssMatroskaExtractor
import io.github.peerless2012.ass.media.factory.AssRenderersFactory
import io.github.peerless2012.ass.media.parser.AssSubtitleParserFactory
import io.github.peerless2012.ass.media.type.AssRenderType

Expand All @@ -20,7 +23,8 @@ fun ExoPlayer.Builder.buildWithAssSupport(
context: Context,
renderType: AssRenderType = AssRenderType.LEGACY,
dataSourceFactory: DataSource.Factory = DefaultDataSource.Factory(context),
extractorsFactory: ExtractorsFactory = DefaultExtractorsFactory()
extractorsFactory: ExtractorsFactory = DefaultExtractorsFactory(),
renderersFactory: RenderersFactory = DefaultRenderersFactory(context)
): ExoPlayer {
val assHandler = AssHandler(renderType)
val assSubtitleParserFactory = AssSubtitleParserFactory(assHandler)
Expand All @@ -35,6 +39,7 @@ fun ExoPlayer.Builder.buildWithAssSupport(

val player = this
.setMediaSourceFactory(mediaSourceFactory)
.setRenderersFactory(renderersFactory.withAssSupport(assHandler))
.build()

assHandler.init(player)
Expand All @@ -57,3 +62,8 @@ fun ExtractorsFactory.withAssMkvSupport(
extractors
}
}

@OptIn(UnstableApi::class)
fun RenderersFactory.withAssSupport(assHandler: AssHandler): RenderersFactory {
return AssRenderersFactory(assHandler, this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import androidx.media3.common.util.UnstableApi
import androidx.media3.effect.CanvasOverlay
import io.github.peerless2012.ass.AssFrame
import io.github.peerless2012.ass.AssRender
import io.github.peerless2012.ass.media.AssHandler
import io.github.peerless2012.ass.media.executor.AssExecutor

@OptIn(UnstableApi::class)
class AssCanvasOverlay(private val render: AssRender) : CanvasOverlay(true) {
class AssCanvasOverlay(private val handler: AssHandler, private val render: AssRender) : CanvasOverlay(true) {

private val paint = Paint().apply {
xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)
Expand All @@ -31,7 +32,12 @@ class AssCanvasOverlay(private val render: AssRender) : CanvasOverlay(true) {
}

override fun onDraw(canvas: Canvas, presentationTimeUs: Long) {
val assFrame: AssFrame? = executor.renderFrame(presentationTimeUs)
val timeUs = if (handler.videoTime >= 0) {
handler.videoTime
} else {
presentationTimeUs
}
val assFrame: AssFrame? = executor.renderFrame(timeUs)

if (assFrame != null && assFrame.changed == 0) {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import androidx.media3.common.util.UnstableApi
import androidx.media3.effect.OverlayEffect
import androidx.media3.exoplayer.ExoPlayer
import io.github.peerless2012.ass.AssRender
import io.github.peerless2012.ass.media.AssHandler

@OptIn(UnstableApi::class)
class AssOverlayManager(
private val handler: AssHandler,
private val player: ExoPlayer,
private val tex: Boolean
) {
Expand All @@ -22,9 +24,9 @@ class AssOverlayManager(
if (renderer == currentRenderer) return
this.currentRenderer = renderer
val overlay = if (tex) {
AssTexOverlay(renderer)
AssTexOverlay(handler, renderer)
} else {
AssCanvasOverlay(renderer)
AssCanvasOverlay(handler, renderer)
}
val effect = OverlayEffect(listOf(overlay))
player.setVideoEffects(listOf(effect))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.github.peerless2012.ass.media.render

import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.NoSampleRenderer
import io.github.peerless2012.ass.media.AssHandler

/**
* @Author peerless2012
* @Email peerless2012@126.com
* @DateTime 5/25/25 10:19 PM
* @Version V1.0
* @Description
*/
@OptIn(UnstableApi::class)
class AssRenderer(private val assHandler: AssHandler): NoSampleRenderer() {

override fun getName(): String {
return "AssRenderer"
}

override fun render(positionUs: Long, elapsedRealtimeUs: Long) {
assHandler.videoTime = positionUs - 1000000000000L
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import androidx.media3.common.util.Size
import androidx.media3.common.util.UnstableApi
import androidx.media3.effect.TextureOverlay
import io.github.peerless2012.ass.AssRender
import io.github.peerless2012.ass.media.AssHandler
import io.github.peerless2012.ass.media.executor.AssExecutor
import java.nio.ByteBuffer
import java.nio.ByteOrder

@OptIn(UnstableApi::class)
class AssTexOverlay(private val render: AssRender) : TextureOverlay() {
class AssTexOverlay(private val handler: AssHandler, private val render: AssRender) : TextureOverlay() {

private val vertexShaderCode = """
attribute vec4 a_Position;
Expand Down Expand Up @@ -77,7 +78,12 @@ class AssTexOverlay(private val render: AssRender) : TextureOverlay() {
private lateinit var executor: AssExecutor

override fun getTextureId(presentationTimeUs: Long): Int {
val assFrame = executor.renderFrame(presentationTimeUs)
val timeUs = if (handler.videoTime >= 0) {
handler.videoTime
} else {
presentationTimeUs
}
val assFrame = executor.renderFrame(timeUs)

// if content not change, just return the tex
if (assFrame != null && assFrame.changed == 0) {
Expand Down