Trimming a video with ExoPlayer and Media3 in Android

I’m a fresh green Android developer looking for a helping hand. I want to trim a video using the Media3 library. Currently I just hardcoded it to cut the video between 1 and 10 sec and it does but then I get an error (see below). I have read through all documentation I can find for Media3 ExoPlayer, transformation and video editing but I’m stuck and I need your help. What am I doing wrong and how can I trim my video, preferably without using a FFMPEG library.

Many thanks in advance!

// ERROR //

E Playback error androidx.media3.exoplayer.ExoPlaybackException: Source error at androidx.media3.exoplayer.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:684) at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:656) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:223) at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: androidx.media3.datasource.FileDataSource$FileDataSourceException: java.io.FileNotFoundException: : open failed: ENOENT (No such file or directory) at androidx.media3.datasource.FileDataSource.openLocalFile(FileDataSource.java:205) at androidx.media3.datasource.FileDataSource.open(FileDataSource.java:116) at androidx.media3.datasource.DefaultDataSource.open(DefaultDataSource.java:272) at androidx.media3.datasource.StatsDataSource.open(StatsDataSource.java:86) at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1006) at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:414) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923)
Caused by: java.io.FileNotFoundException: : open failed: ENOENT (No such file or directory) at libcore.io.IoBridge.open(IoBridge.java:492) at java.io.RandomAccessFile.(RandomAccessFile.java:289) at java.io.RandomAccessFile.(RandomAccessFile.java:152) at androidx.media3.datasource.FileDataSource.openLocalFile(FileDataSource.java:186) at androidx.media3.datasource.FileDataSource.open(FileDataSource.java:116)  at androidx.media3.datasource.DefaultDataSource.open(DefaultDataSource.java:272)  at androidx.media3.datasource.StatsDataSource.open(StatsDataSource.java:86)  at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1006)  at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:414)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  at java.lang.Thread.run(Thread.java:923) 
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) at libcore.io.Linux.open(Native Method) at libcore.io.ForwardingOs.open(ForwardingOs.java:166) at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254) at libcore.io.ForwardingOs.open(ForwardingOs.java:166) at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542) at libcore.io.IoBridge.open(IoBridge.java:478) at java.io.RandomAccessFile.(RandomAccessFile.java:289)  at java.io.RandomAccessFile.(RandomAccessFile.java:152)  at androidx.media3.datasource.FileDataSource.openLocalFile(FileDataSource.java:186)  at androidx.media3.datasource.FileDataSource.open(FileDataSource.java:116)  at androidx.media3.datasource.DefaultDataSource.open(DefaultDataSource.java:272)  at androidx.media3.datasource.StatsDataSource.open(StatsDataSource.java:86)  at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1006)  at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:414)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)  at java.lang.Thread.run(Thread.java:923) 

// MY CODE //

`fun trimVideo() {
        val uri = player.currentMediaItem?.mediaId?.toUri()
        if (uri != null) {
            player.setMediaItem(
                videoTrimmer.trimVideo(uri, 1000, 10000)
            ) ...


interface VideoTrimmer {
    fun trimVideo(uri: Uri, startTimeInMs: Long, endTimeInMs: Long): MediaItem
}

class VideoTrimmerImpl(): VideoTrimmer {
    override fun trimVideo(uri: Uri, startTimeInMs: Long, endTimeInMs: Long): MediaItem {

        val inputMediaItem = MediaItem.Builder()
            .setUri(uri)
            .setClippingConfiguration(
                MediaItem.ClippingConfiguration.Builder()
                    .setStartPositionMs(startTimeInMs)
                    .setEndPositionMs(endTimeInMs)
                    .build())
            .build()
        return inputMediaItem
    }
}

Leave a Comment