Giter VIP home page Giter VIP logo

natario1 / transcoder Goto Github PK

View Code? Open in Web Editor NEW
747.0 28.0 161.0 3.47 MB

๐ŸŽž Hardware-accelerated video transcoding using Android MediaCodec APIs. Supports cropping, concatenation, clipping, audio processing, video speed and much more.

Home Page: https://natario1.github.io/Transcoder

License: Apache License 2.0

Java 59.72% Kotlin 40.28%
android android-library video-processing video-compressor egl opengl opengl-es mediacodec hardware-acceleration mp4

transcoder's Introduction

Build Status Release Issues

โ €

Looking for a powerful camera library to take videos? Take a look at our CameraView.

Need support, consulting, or have any other business-related question? Feel free to get in touch.

Like the project, make profit from it, or simply want to thank back? Please consider sponsoring me!

Transcoder

Transcodes and compresses video files into the MP4 format, with audio support, using hardware-accelerated Android codecs available on the device. Works on API 18+.

implementation 'com.otaliastudios:transcoder:0.10.5'
  • Fast transcoding to AAC/AVC
  • Hardware accelerated
  • Convenient, fluent API
  • Thumbnails support
  • Concatenate multiple video and audio tracks [docs]
  • Clip or trim video segments [docs]
  • Choose output size, with automatic cropping [docs]
  • Choose output rotation [docs]
  • Choose output speed [docs]
  • Choose output frame rate [docs]
  • Choose output audio channels [docs]
  • Choose output audio sample rate [docs]
  • Override frames timestamp, e.g. to slow down the middle part of the video [docs]
  • Error handling [docs]
  • Configurable validators to e.g. avoid transcoding if the source is already compressed enough [docs]
  • Configurable video and audio strategies [docs]

โ €

โ €

This project started as a fork of ypresto/android-transcoder. With respect to the source project, which misses most of the functionality listed above, we have also fixed a huge number of bugs and are much less conservative when choosing options that might not be supported. The source project will always throw - for example, accepting only 16:9, AVC Baseline Profile videos - we prefer to try and let the codec fail if it wants to.

Support

If you like the project, make profit from it, or simply want to thank back, please consider sponsoring me through the GitHub Sponsors program! You can have your company logo here, get private support hours or simply help me push this forward.

Transcoder is trusted and supported by ShareChat, a social media app with over 100 million downloads.

Feel free to contact me for support, consulting or any other business-related question.

Setup

Please read the official website for setup instructions and documentation. You might also be interested in our changelog. Using Transcoder is extremely simple:

Transcoder.into(filePath)
        .addDataSource(context, uri) // or...
        .addDataSource(filePath) // or...
        .addDataSource(fileDescriptor) // or...
        .addDataSource(dataSource)
        .setListener(new TranscoderListener() {
             public void onTranscodeProgress(double progress) {}
             public void onTranscodeCompleted(int successCode) {}
             public void onTranscodeCanceled() {}
             public void onTranscodeFailed(@NonNull Throwable exception) {}
        }).transcode()

Take a look at the demo app for a complete example.

transcoder's People

Contributors

aaron112 avatar aweck avatar cbernier avatar damonchen117 avatar dependabot[bot] avatar hkurokawa avatar jumperson avatar maikambayashi avatar mudar avatar natario1 avatar pawegio avatar ryanwilliams83 avatar spiritedrunning avatar tateisu avatar vanniktech avatar veneetreddyk avatar ypresto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

transcoder's Issues

MutedAudio strategy for media without audio track

I'm trying to concatenate multiple videos where some would be missing the audio track. Is this a feature you're planning to add to the library?
I tried some code changes, and I was able to concatenate when all files are missing the audio track (result would not have an audio track). I was also able to mute audio if the track was available in the source.
However, I was not able to create the empty buffer manually. Do you have any hints that could guide me to find the right steps. I have looked around, and didn't find any solutions similar to this.

Transcoding is stuck for a specific video file

Using the demo app with default settings, transcoding on the video freezes. Can be reproduced on Android emulator.

Video file: https://drive.google.com/file/d/13vqvOQ9VkUOLrr2EtT1pLdm9wB6ZUL-n/view?usp=sharing

After further investigation, it seems that audio is failing to decode and output always has size 0. The file plays fine on the device though.

Selecting "remove audio" allows compression to succeed.

Logs (log statements added by me) - it repeats forever

2020-09-25 13:41:25.808 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=2 size=2
2020-09-25 13:41:25.828 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 1
2020-09-25 13:41:25.828 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 1
2020-09-25 13:41:25.829 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 2
2020-09-25 13:41:25.829 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 2
2020-09-25 13:41:25.829 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 3
2020-09-25 13:41:25.829 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 3
2020-09-25 13:41:25.831 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=2 size=2
2020-09-25 13:41:25.831 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 0
2020-09-25 13:41:25.831 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 0
2020-09-25 13:41:25.832 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 1
2020-09-25 13:41:25.832 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 1
2020-09-25 13:41:25.832 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 2
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 2
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 3
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 3
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 0
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 0
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 1
2020-09-25 13:41:25.833 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 1
2020-09-25 13:41:25.834 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: 2
2020-09-25 13:41:25.834 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Queue input buffer: 2
2020-09-25 13:41:25.837 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -3 flags=2 size=2
2020-09-25 13:41:25.838 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -2 flags=2 size=2
2020-09-25 13:41:25.839 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: 0 flags=0 size=0
2020-09-25 13:41:25.839 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO NOT calling onDrainDecoder
2020-09-25 13:41:25.839 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.840 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: 1 flags=0 size=0
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO NOT calling onDrainDecoder
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: 2 flags=0 size=0
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO NOT calling onDrainDecoder
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.841 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.842 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: 3 flags=0 size=0
2020-09-25 13:41:25.842 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO NOT calling onDrainDecoder
2020-09-25 13:41:25.842 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.842 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.843 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=0 size=0
2020-09-25 13:41:25.843 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.843 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.854 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=0 size=0
2020-09-25 13:41:25.854 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.854 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.865 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=0 size=0
2020-09-25 13:41:25.865 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.865 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.876 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=0 size=0
2020-09-25 13:41:25.876 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.876 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.887 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=0 size=0
2020-09-25 13:41:25.887 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false
2020-09-25 13:41:25.887 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue input buffer: -1
2020-09-25 13:41:25.928 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO Dequeue output buffer: -1 flags=0 size=0
2020-09-25 13:41:25.928 19371-19471/com.otaliastudios.transcoder.demo V/BUFFER: AUDIO feedEncoder hasPendingBuffers(): false

Error 0x80001001

I/Transcodingย into: /data/user/0/club.fishopclub.fishopapp/cache/fishopTemp/asddaaaa7662049941698810190.mp4
V/NuMediaExtractor: setDataSource fd=79 (/storage/emulated/0/Download/cupangkeren.mp4), offset=0, length=576460752303423487
W/FileSource: offset/length adjusted from 0/576460752303423487 to 0/7817688
V/NuMediaExtractor: track of type 'video/avc' does not publish bitrate
track of type 'audio/mp4a-latm' does not publish bitrate
I/DefaultVideoStrategy: Input width&height: 360x360
I/DefaultVideoStrategy: Output width&height: 180x180
V/Engine: Duration (us): 127663000
new step: 0
I/OMXClient: Treble IOmx obtained
E/ACodec: [OMX.google.aac.encoder] configureCodec returning error -2147483648
signalError(omxError 0x80001001, internalError -2147483648)
E/MediaCodec: Codec reported err 0x80001001, actionCode 0, while in state 3
E/MediaCodec: configure failed with err 0x80001001, resetting...
I/OMXClient: Treble IOmx obtained
E/Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android.
android.media.MediaCodec$CodecException: Error 0x80001001
at android.media.MediaCodec.native_configure(Native Method)
at android.media.MediaCodec.configure(MediaCodec.java:1943)
at android.media.MediaCodec.configure(MediaCodec.java:1872)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.onConfigureEncoder(BaseTrackTranscoder.java:86)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.setUp(BaseTrackTranscoder.java:63)
at com.otaliastudios.transcoder.engine.Engine.openCurrentStep(Engine.java:194)
at com.otaliastudios.transcoder.engine.Engine.getCurrentTrackTranscoder(Engine.java:223)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:370)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)

Issue with v0.9.1. Build failed

Duplicate class com.otaliastudios.opengl.BuildConfig found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.core.EglConfigChooser found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.core.EglConfigChooser$Chooser found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.core.EglContextFactory found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.core.EglContextFactory$Factory found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.core.EglCore found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.core.EglCore$Companion found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.surface.EglSurface found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.surface.EglSurface$Companion found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)
Duplicate class com.otaliastudios.opengl.surface.EglWindowSurface found in modules jetified-egl-core-0.1.1-runtime.jar (com.otaliastudios.opengl:egl-core:0.1.1) and jetified-egloo-0.4.0-runtime.jar (com.otaliastudios.opengl:egloo:0.4.0)

Failed to stop the muxer

I am trying to cut a video recorded by my phone. When cutting, the following error is displayed:
Failed to stop the muxer
video path : /storage/emulated/0/Android/data/com.vitor.videoeditor/files/Movies/Speeacht/VID_20200718_121633.mp4
destine path: /storage/emulated/0/Android/data/com.vitor.videoeditor/files/Movies/Speeacht/VID_20200718_121643.mp4

my code:

 private fun clipVideos() {

        videoPath = intent.extras?.getString("video")
        Log.i("VIDEOEDITOR","path - $videoPath")
        val uri = Uri.fromFile(File(videoPath))

        val dataSource = UriDataSource(this,uri)
        val duration = dataSource.durationUs

        val startTime: Long = 0
        val endTime: Long = if (duration > 3000) 3000 else duration
        val clip = ClipDataSource(dataSource, startTime, endTime)

        val diretorioSaida = FileUtils.getVideosDir(this).absolutePath

        val destPath = (diretorioSaida + File.separator + FileUtils.VIDEO_PREFIX
                + LocalTimeUtils.getFormatedTime()
                + FileUtils.VIDEO_EXTENSION)

        Log.i("VIDEOEDITOR","Dest - $destPath")

        Transcoder.into(destPath)
                .addDataSource(clip)
                .setListener(object : TranscoderListener {
                    override fun onTranscodeCompleted(successCode: Int) {
                        videoList.add(destPath)
                        recyclerVideos.adapter?.notifyDataSetChanged()
                        toast("OK!")
                    }

                    override fun onTranscodeProgress(progress: Double) {
                        Log.i("PROGRESS", progress.toString())
                    }

                    override fun onTranscodeCanceled() {
                        toast("CANCELED")
                    }

                    override fun onTranscodeFailed(exception: Throwable) {
                        Log.i("VIDEOEDITOR",exception.message.toString())
                    }

                }).transcode()


    }

How to fix this error?
Another question: is it possible to cut a video for example every 3 seconds?

Transcoding Failure on Android 5

In Android 5, Video transcoding is getting failed. This is the stack trace.

Device used : Honor Bee (Android 5)
Observed on Intex and Vivo devices (all Android 5)

Stacktrace:

    java.lang.RuntimeException: Could not get a complete format! hasMimeType:true hasWidth:true hasHeight:true hasFrameRate:false
        at com.otaliastudios.transcoder.engine.MediaFormatProvider.provideMediaFormat(MediaFormatProvider.java:57)
        at com.otaliastudios.transcoder.engine.Engine.computeTrackStatus(Engine.java:122)
        at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:326)
        at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
        at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:831)```

Input videos of different rotations

I have four videos, one in each rotation of 0, 90, 180, 270.

2 of them are 3840x2160 (horizontal) and the other 2 are 2160x3840 (vertical). When I transcode them, the output file is 2160x3840(vertical) and the inputted horizontal clips are trimmed to be 9:16 aspect ration, just like the 2 vertical inputs.

I have tried the following to set the output file to 16:9.

transcodeBuilder.setVideoTrackStrategy(DefaultVideoStrategy.Builder() .addResizer(AspectRatioResizer(16F / 9F)) .build())

I add the multiple sources to the transcoder using
transcodeBuilder.addDataSource(absoluteFilePath: String)

but the output is still vertical.

This is the case no matter the input order of the videos.

Is there a way to set the aspect ratio to 16:9 and do no chopping on vertical videos, having the black bars is fine.

Thanks for your help

Audio/Video out of sync problem concatenating

using version: 0.9.0

I'm concatenating several videos and as a result I'm getting a video with a big sync delay with audio. Videos are taken from camera using CameraView library. I'm aware that a video recorded by phone camera usually has audio/video different lengths and that that is provoking the problem..but shouldn't be the transcoder taking care of it.

Output channel count (6) not supported

Transcoder throws UnsupportedOperationException, when I'm trying to transcode video with 6 audio channels. Is it a real engine limitation?

java.lang.UnsupportedOperationException: Output channel count (6) not supported.
    at com.otaliastudios.transcoder.transcode.internal.AudioEngine.<init>(AudioEngine.java:83)
    at com.otaliastudios.transcoder.transcode.AudioTrackTranscoder.onDecoderOutputFormatChanged(AudioTrackTranscoder.java:56)
    at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.drainDecoder(BaseTrackTranscoder.java:240)
    at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.transcode(BaseTrackTranscoder.java:165)
    at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:368)
    at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
    at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    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:919)

kotlin

please convert source to kotlin

Transcoding error because of faulty ExactSize class

We got the following exception while trying to transcode a video:

E/MediaTranscoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android. 
 android.media.MediaCodec$CodecException: Error 0xfffffc0e
 at android.media.MediaCodec.native_configure(Native Method)
        at android.media.MediaCodec.configure(MediaCodec.java:1967)
        at android.media.MediaCodec.configure(MediaCodec.java:1896)
        at com.otaliastudios.transcoder.transcode.VideoTrackTranscoder.setup(VideoTrackTranscoder.java:88)
        at com.otaliastudios.transcoder.engine.MediaTranscoderEngine.setupTrackTranscoders(MediaTranscoderEngine.java:213)
        at com.otaliastudios.transcoder.engine.MediaTranscoderEngine.transcode(MediaTranscoderEngine.java:106)
        at com.otaliastudios.transcoder.MediaTranscoder$1.call(MediaTranscoder.java:123)
        at com.otaliastudios.transcoder.MediaTranscoder$1.call(MediaTranscoder.java:111)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        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:784)

After some debugging, and some confused staring at the code below, it quickly became obvious what the culprit was :)

package com.otaliastudios.transcoder.strategy.size;

/**
 * A special {@link Size} that knows about which dimension is width
 * and which is height.
 *
 * See comments in {@link Resizer}.
 */
public class ExactSize extends Size {

    private int mWidth;
    private int mHeight;

    public ExactSize(int width, int height) {
        super(width, height);
    }

    public int getWidth() {
        return mWidth;
    }

    public int getHeight() {
        return mHeight;
    }
}

Actually setting the private fields from the constructor fixed the issue.

Input channel count (6) not supported

Particular reason for this limitation?

If I comment out AudioEngine.java lines 85-87 and use output channel count of 2, transcoding occurs just fine. Would pull request with removed check be acceptable? Alternatively, removal of this check may be optional, opt-in via AudioStrategy parameters for example...

use mExtractor and mMetadata after released

I'm joining audio only files.

the release() was called by:
release:208, DefaultDataSource (com.otaliastudios.transcoder.source)
release:62, FilePathDataSource (com.otaliastudios.transcoder.source)
releaseTrack:202, DefaultDataSource (com.otaliastudios.transcoder.source)
closeCurrentStep:203, Engine (com.otaliastudios.transcoder.engine)
getCurrentTrackTranscoder:216, Engine (com.otaliastudios.transcoder.engine)
transcode:371, Engine (com.otaliastudios.transcoder.engine)
call:150, Transcoder$1 (com.otaliastudios.transcoder)
call:140, Transcoder$1 (com.otaliastudios.transcoder)
run:237, FutureTask (java.util.concurrent)
runWorker:1112, ThreadPoolExecutor (java.util.concurrent)
run:587, ThreadPoolExecutor$Worker (java.util.concurrent)
run:818, Thread (java.lang)

then mExtractor and mMetadata were used later and IllegalStateException throw from android native

mMetadataApplied and mExtractorApplied should be updated when release.

protected void release() {
try {
mExtractor.release();
} catch (Exception e) {
LOG.w("Could not release extractor:", e);
}
try {
mMetadata.release();
} catch (Exception e) {
LOG.w("Could not release metadata:", e);
}
}

Exception transcoding avi on Vivo y81i android 8.1

DefaultDataSink: Failed to release the muxer.
java.lang.IllegalStateException: Failed to stop the muxer
at android.media.MediaMuxer.nativeStop(Native Method)
at android.media.MediaMuxer.stop(MediaMuxer.java:457)
at android.media.MediaMuxer.release(MediaMuxer.java:696)
at com.otaliastudios.transcoder.sink.DefaultDataSink.release(DefaultDataSink.java:189)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:390)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android.
java.lang.IllegalStateException: writeSampleData returned an error
at android.media.MediaMuxer.nativeWriteSampleData(Native Method)
at android.media.MediaMuxer.writeSampleData(MediaMuxer.java:684)
at com.otaliastudios.transcoder.sink.DefaultDataSink.writeTrack(DefaultDataSink.java:134)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.drainEncoder(BaseTrackTranscoder.java:288)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.transcode(BaseTrackTranscoder.java:163)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:369)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
VideosKt$cutVideoTo15Seconds: java.lang.IllegalStateException: writeSampleData returned an error
at android.media.MediaMuxer.nativeWriteSampleData(Native Method)
at android.media.MediaMuxer.writeSampleData(MediaMuxer.java:684)
at com.otaliastudios.transcoder.sink.DefaultDataSink.writeTrack(DefaultDataSink.java:134)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.drainEncoder(BaseTrackTranscoder.java:288)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.transcode(BaseTrackTranscoder.java:163)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:369)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)

Error 0xffffec77

Somehow I constantly get the following error 0xffffec77 on multiple devices (Samsung + Xaomi). Min SDK is 21. Any idea what might cause it? Even when I keep my config to defaults:

                val mTranscodeVideoStrategy = DefaultVideoStrategy.Builder()
                    .bitRate(TARGET_VIDEO_BITRATE.toLong())
                    //.addResizer(if (aspectRatio > 0) AspectRatioResizer(aspectRatio) else PassThroughResizer())
                    //.addResizer(AtMostResizer(TARGET_VIDEO_HEIGHT))
                    //.addResizer(ExactResizer(Size(TARGET_VIDEO_WIDTH, TARGET_VIDEO_HEIGHT)))
                    .build()

                val future = Transcoder
                    .into(compressedFilePath)
                    .setVideoTrackStrategy(mTranscodeVideoStrategy)
                    .addDataSource(sourceFilePath)
                    .setListener(this).transcode()
                future.get()

The video is perfectly playable and all permissions are given.
I suspect this line to be the cause:
2019-11-16 11:32:40.513 32514-1162/com.clash.android.debug E/ACodec: configureCodec multi window instance fail appPid : 32514
Does that mean that the codec is already used somewhere? But that may not even be by the same app? I tried transcoding a video file that's never actually played by any MediaPlayer or even loaded as a image by Glide, same result.
Here is the stacktrace:

[2019-11-16 11:13:15.836 26907-28900/com.test.android.debug D/CompressFileWorker: start compressing
2019-11-16 11:13:15.857 26907-28901/com.test.android.debug W/FileSource: offset/length adjusted from 0/576460752303423487 to 0/4206980
2019-11-16 11:13:15.888 26907-28901/com.test.android.debug I/DefaultVideoStrategy: Input width&height: 1920x1080
2019-11-16 11:13:15.888 26907-28901/com.test.android.debug I/DefaultVideoStrategy: Output width&height: 1920x1080
2019-11-16 11:13:15.890 26907-28901/com.test.android.debug V/Engine: Duration (us): 11609000
2019-11-16 11:13:15.890 26907-28901/com.test.android.debug V/Engine: new step: 0
2019-11-16 11:13:15.894 26907-28901/com.test.android.debug I/ACodec:  [] Now uninitialized
2019-11-16 11:13:15.895 26907-28902/com.test.android.debug I/ACodec: [] onAllocateComponent
2019-11-16 11:13:15.896 26907-28902/com.test.android.debug I/OMXClient: MuxOMX ctor
2019-11-16 11:13:15.896 26907-28902/com.test.android.debug I/ACodec: Set Google AAC Dec for aacProfile 0
2019-11-16 11:13:15.906 26907-28902/com.test.android.debug I/ACodec: [OMX.google.aac.encoder] Now Loaded
2019-11-16 11:13:15.909 26907-28902/com.test.android.debug I/ACodec: [OMX.google.aac.encoder] Now Loaded->Idle
2019-11-16 11:13:15.912 26907-28902/com.test.android.debug I/ACodec: [OMX.google.aac.encoder] Now Idle->Executing
2019-11-16 11:13:15.913 26907-28902/com.test.android.debug I/ACodec: [OMX.google.aac.encoder] Now Executing
2019-11-16 11:13:15.914 26907-28901/com.test.android.debug I/ACodec:  [] Now uninitialized
2019-11-16 11:13:15.915 26907-28905/com.test.android.debug I/ACodec: [] onAllocateComponent
2019-11-16 11:13:15.916 26907-28905/com.test.android.debug I/OMXClient: MuxOMX ctor
2019-11-16 11:13:15.916 26907-28905/com.test.android.debug I/ACodec: Set Google AAC Dec for aacProfile 0
2019-11-16 11:13:15.924 26907-28905/com.test.android.debug I/ACodec: [OMX.google.aac.decoder] Now Loaded
2019-11-16 11:13:15.927 26907-28905/com.test.android.debug I/ACodec: [OMX.google.aac.decoder] Now Loaded->Idle
2019-11-16 11:13:15.931 26907-28905/com.test.android.debug I/ACodec: [OMX.google.aac.decoder] Now Idle->Executing
2019-11-16 11:13:15.932 26907-28905/com.test.android.debug I/ACodec: [OMX.google.aac.decoder] Now Executing
2019-11-16 11:13:15.936 26907-28905/com.test.android.debug I/ACodec: [OMX.google.aac.decoder] Now handling output port settings change
2019-11-16 11:13:15.940 26907-28905/com.test.android.debug I/ACodec: [OMX.google.aac.decoder] Now Executing
2019-11-16 11:13:15.949 26907-28901/com.test.android.debug I/ACodec:  [] Now uninitialized
2019-11-16 11:13:15.950 26907-28909/com.test.android.debug I/ACodec: [] onAllocateComponent
2019-11-16 11:13:15.951 26907-28909/com.test.android.debug I/OMXClient: MuxOMX ctor
2019-11-16 11:13:15.951 26907-28909/com.test.android.debug I/ACodec: Set Google AAC Dec for aacProfile 0
2019-11-16 11:13:15.985 26907-28909/com.test.android.debug I/ACodec: [OMX.Exynos.AVC.Encoder] Now Loaded
2019-11-16 11:13:15.990 26907-28909/com.test.android.debug W/ACodec: do not know color format 0x7f000011 = 2130706449
2019-11-16 11:13:15.991 26907-28909/com.test.android.debug W/ACodec: do not know color format 0x10 = 16
2019-11-16 11:13:15.991 26907-28909/com.test.android.debug W/ACodec: do not know color format 0x7f00a000 = 2130747392
2019-11-16 11:13:15.992 26907-28909/com.test.android.debug W/ACodec: do not know color format 0x7f000789 = 2130708361
2019-11-16 11:13:15.996 26907-28909/com.test.android.debug I/ACodec: setupAVCEncoderParameters with [profile: Baseline] [level: Level1]
2019-11-16 11:13:15.997 26907-28909/com.test.android.debug I/ACodec: Enable perceptual video coding
2019-11-16 11:13:15.997 26907-28909/com.test.android.debug I/ACodec: Success set VideoMinQP(5/5/5) VideoMaxQP(50/50/50)
2019-11-16 11:13:15.999 26907-28909/com.test.android.debug I/ACodec: [OMX.Exynos.AVC.Encoder] cannot encode HDR static metadata. Ignoring.
2019-11-16 11:13:15.999 26907-28909/com.test.android.debug I/ACodec: setupVideoEncoder succeeded
2019-11-16 11:13:16.000 26907-28909/com.test.android.debug W/ACodec: do not know color format 0x7f000789 = 2130708361
2019-11-16 11:13:16.011 26907-28901/com.test.android.debug D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000,  [1920x1080]-format:1
2019-11-16 11:13:16.013 26907-28909/com.test.android.debug I/ACodec: [OMX.Exynos.AVC.Encoder] Now Loaded->Idle
2019-11-16 11:13:16.034 26907-28901/com.test.android.debug I/ACodec:  [] Now uninitialized
2019-11-16 11:13:16.052 26907-28921/com.test.android.debug I/ACodec: [] onAllocateComponent
2019-11-16 11:13:16.054 26907-28909/com.test.android.debug I/ACodec: [OMX.Exynos.AVC.Encoder] Now Idle->Executing
2019-11-16 11:13:16.054 26907-28921/com.test.android.debug I/OMXClient: MuxOMX ctor
2019-11-16 11:13:16.054 26907-28921/com.test.android.debug I/ACodec: Set Google AAC Dec for aacProfile 0
2019-11-16 11:13:16.056 26907-28909/com.test.android.debug I/ACodec: [OMX.Exynos.AVC.Encoder] Now Executing
2019-11-16 11:13:16.063 26907-28921/com.test.android.debug I/ACodec: [OMX.Exynos.avc.dec] Now Loaded
2019-11-16 11:13:16.070 26907-28918/com.test.android.debug I/MediaCodec: [OMX.Exynos.avc.dec] setting surface generation to 27552774
2019-11-16 11:13:16.071 26907-28921/com.test.android.debug I/ACodec: can't find wfdsink-exynos-enable
2019-11-16 11:13:16.075 26907-28921/com.test.android.debug E/ACodec:  configureCodec multi window instance fail  appPid : 26907
2019-11-16 11:13:16.076 26907-28921/com.test.android.debug E/ACodec: [OMX.Exynos.avc.dec] configureCodec returning error -5001
2019-11-16 11:13:16.077 26907-28921/com.test.android.debug E/ACodec: signalError(omxError 0x80001001, internalError -5001)
2019-11-16 11:13:16.077 26907-28918/com.test.android.debug E/MediaCodec: Codec reported err 0xffffec77, actionCode 0, while in state 3
2019-11-16 11:13:16.077 26907-28901/com.test.android.debug E/MediaCodec: configure failed with err 0xffffec77, resetting...
2019-11-16 11:13:16.080 26907-28921/com.test.android.debug I/ACodec:  [OMX.Exynos.avc.dec] Now uninitialized
2019-11-16 11:13:16.080 26907-28921/com.test.android.debug I/ACodec:  [] Now kWhatShutdownCompleted event : 8554
2019-11-16 11:13:16.080 26907-28918/com.test.android.debug I/MediaCodec: Codec shutdown complete
2019-11-16 11:13:16.081 26907-28901/com.test.android.debug I/ACodec:  [] Now uninitialized
2019-11-16 11:13:16.081 26907-28921/com.test.android.debug I/ACodec: [] onAllocateComponent
2019-11-16 11:13:16.083 26907-28921/com.test.android.debug I/OMXClient: MuxOMX ctor
2019-11-16 11:13:16.083 26907-28921/com.test.android.debug I/ACodec: Set Google AAC Dec for aacProfile 0
2019-11-16 11:13:16.090 26907-28921/com.test.android.debug I/ACodec: [OMX.Exynos.avc.dec] Now Loaded
2019-11-16 11:13:16.092 26907-28901/com.test.android.debug E/Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android.
    android.media.MediaCodec$CodecException: Error 0xffffec77
        at android.media.MediaCodec.native_configure(Native Method)
        at android.media.MediaCodec.configure(MediaCodec.java:1882)
        at com.otaliastudios.transcoder.transcode.VideoTrackTranscoder.onConfigureDecoder(VideoTrackTranscoder.java:105)
        at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.setUp(BaseTrackTranscoder.java:75)
        at com.otaliastudios.transcoder.engine.Engine.openCurrentStep(Engine.java:190)
        at com.otaliastudios.transcoder.engine.Engine.getCurrentTrackTranscoder(Engine.java:219)
        at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:371)
        at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
        at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:762)](url)

Exception on mkv transcoding on Vivo Y81i Android 8.1

java.nio.BufferOverflowException
at java.nio.ByteBuffer.put(ByteBuffer.java:544)
at com.otaliastudios.transcoder.sink.DefaultDataSink.enqueue(DefaultDataSink.java:156)
at com.otaliastudios.transcoder.sink.DefaultDataSink.writeTrack(DefaultDataSink.java:136)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.drainEncoder(BaseTrackTranscoder.java:288)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.transcode(BaseTrackTranscoder.java:163)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:369)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
VideosKt$cutVideoTo15Seconds: java.nio.BufferOverflowException
at java.nio.ByteBuffer.put(ByteBuffer.java:544)
at com.otaliastudios.transcoder.sink.DefaultDataSink.enqueue(DefaultDataSink.java:156)
at com.otaliastudios.transcoder.sink.DefaultDataSink.writeTrack(DefaultDataSink.java:136)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.drainEncoder(BaseTrackTranscoder.java:288)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.transcode(BaseTrackTranscoder.java:163)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:369)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)

Overlaying text on the individual clips

I was just wondering if it would be possible to add support for adding a text overlay to the datasources? Or an image over the final product.

I could even try to implement it myself if you steered me in the right direction. Thanks!

DataSink FileDescriptor support

Hi Mattia, I hope you're doing fine...

I'm creating this issue to link it to a PR: the DefaultDataSink constructor relies on the file path. I feel it would be useful to add a constructor that uses a FileDescriptor, especially for Android 10.

thanks,
mudar

Fatal exception in DefaultAudioStrategy on video without audio

When I try to transcode video without audio track fatal exception is thrown:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
       at android.media.MediaFormat.getInteger + 998(MediaFormat.java:998)
       at com.otaliastudios.transcoder.strategy.DefaultAudioStrategy.getInputChannelCount + 115(DefaultAudioStrategy.java:115)
       at com.otaliastudios.transcoder.strategy.DefaultAudioStrategy.createOutputFormat + 100(DefaultAudioStrategy.java:100)
       at com.otaliastudios.transcoder.engine.Engine.computeTrackStatus + 126(Engine.java:126)
       at com.otaliastudios.transcoder.engine.Engine.transcode + 322(Engine.java:322)
       at com.otaliastudios.transcoder.Transcoder$1.call + 134(Transcoder.java:134)
       at com.otaliastudios.transcoder.Transcoder$1.call + 124(Transcoder.java:124)
       at java.util.concurrent.FutureTask.run + 266(FutureTask.java:266)
       at java.util.concurrent.ThreadPoolExecutor.runWorker + 1167(ThreadPoolExecutor.java:1167)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run + 641(ThreadPoolExecutor.java:641)
       at java.lang.Thread.run + 764(Thread.java:764)

I use single parameter addDataSource function without specifying TrackType so I expected audio track to be ignored when it's not included in the input file.

Trancoding video ON THE GO ?

Hey Is there any possibility to add transcoding for a LIVE media streaming URL and play that transcoded video at the same time on Exo player or any other media player.

Slow cropping to 1:1 aspect ratio

I'm cropping a 90 seconds video with 19201080 resolution to a 10801080 video. It takes 50 seconds, is there any way to boost this?

This is the code I'm using:

        val strategy = DefaultVideoStrategy.Builder()
            .addResizer(AspectRatioResizer(1F / 1F)).build()

        Transcoder.into(videoName)
            .setVideoTrackStrategy(strategy)
            .setListener(listener)
            .addDataSource(sourcePath)
            .transcode()

video transitions

please add the transitions and effect in your library. is already a great work

Resampling an audio data source causes noise

Downsampling is better that upsampling, but still it causes a lot of noise. The main reason seem to be because the buffers that get processed (resampled) are very small (~2048 bytes) so the approximations is bad for about 0.1% of the samples. Increasing the decoder output buffer size helps a lot but unfortunately it was not that simple : cbernier@86986f9
Is there a simpler way?

Adding multiple clip data source is not decreasing the video length

I have added 2 clip data source into the transcoder. The total video length is 7s.
I have added clip source 1 for 0 to 1s and clip source 2 for 3 to 7s. The video should be of 5s.
But the final video has content of 5s but at the end last 2s video is kind of paused.

Original video link - https://drive.google.com/file/d/1qI766r8pMRJMlIptaoPEDK_xfSwuLO97/view?usp=sharing
Final Result link - https://drive.google.com/file/d/1A4VVkKquLYMcVNj1rHVACXvSPJg7iNr_/view?usp=sharing

Device used : Redmi Y2

Code used

        val dataSink = DefaultDataSink(videoFile.absolutePath)
        val builder = Transcoder.into(dataSink)
                .addDataSource(ClipDataSource(UriDataSource(applicationContext, Uri.parse(inputSource.absolutePath)), 0, 1000 * 1000))
                .addDataSource(ClipDataSource(UriDataSource(applicationContext, Uri.parse(inputSource.absolutePath)), 3000 * 1000, 7000 * 1000))
        builder.setListener(object : TranscoderListener {
            override fun onTranscodeCompleted(successCode: Int) {
                Logger.v(TAG, "cutout final video, completed")
            }

            override fun onTranscodeProgress(progress: Double) {
                Logger.v(TAG, "cutout final video, progress - $progress")
            }

            override fun onTranscodeCanceled() {
                Logger.v(TAG, "cutout final video, canceled")
            }

            override fun onTranscodeFailed(exception: Throwable) {
                Logger.v(TAG, "cutout final video, failed")
                exception.printStackTrace()
            }

        }).transcode()

Does it work on Android Q devices?

Hi there I've been trying in on an emulator running android q and I got this following error.

Fatal error while transcoding, this might be invalid format or bug in engine or Android. java.lang.IllegalArgumentException: Failed to initialize video/avc, error 0xfffffffe at android.media.MediaCodec.native_setup(Native Method) at android.media.MediaCodec.<init>(MediaCodec.java:1864) at android.media.MediaCodec.createEncoderByType(MediaCodec.java:1827) at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.setUp(BaseTrackTranscoder.java:59) at com.otaliastudios.transcoder.engine.Engine.openCurrentStep(Engine.java:190) at com.otaliastudios.transcoder.engine.Engine.getCurrentTrackTranscoder(Engine.java:219) at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:371) at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134) at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124) at java.util.concurrent.FutureTask.run(FutureTask.java:266) 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:919)

It happens only in API 29

Hi! - sponsoring Transcoder development

Hi! ๐Ÿ‘‹

I am Mattia, the main developer and maintainer here, and I have enabled the GitHub Sponsor button on this repository which will let you support the library development by sponsoring my open source work through GitHub itself.

In the last years, I have spent countless unpaid hours on this and other projects, designing and developing tools that solve real problems, for everyone to use. I am very happy to know that companies of all sizes benefit from my work everyday.

GitHub is now offering you the opportunity to thank back with a sponsorship. For individuals, it could be a small amount. For companies that are powered by my tools, it could be a fairly small percentage of their revenue. In any case, your support will be greatly appreciated (and for bigger amounts, you get things like private support hours, or something else if you prefer).

https://github.com/sponsors/natario1

I will experiment leaving this as a pinned issue - for a while at least - since it's where people are most likely to see it. Sorry if this bothers you, and thank you all for your help.

File Size is increased after transcode in some phones ex:Samsung S8 Device

Actually I have uploaded 206MB video to transcode it gives 900MB video back as a result.
Please find below strategy which I have used

                   DefaultVideoStrategy mTranscodeVideoStrategy = new DefaultVideoStrategy.Builder()
                    .addResizer(new AspectRatioResizer(16F / 9F))
                    .addResizer(new FractionResizer(1F))
                    .frameRate(24)
                    .bitRate(Math.min(Integer.parseInt(s), 1000000))
                    .keyFrameInterval(100)
                    .build(); 

======================================================

                    mTranscodeFuture = Transcoder.
                    into(file.getAbsolutePath())
                    .addDataSource(context, mediaUri)
                    .setVideoTrackStrategy(mTranscodeVideoStrategy)
                    .transcode();

=========================================================

please help me out thank you in advance.

Speed up part of video

thank you for great libary, as title, Is it possible to only apply the speedup in certain regions in the video. Eg. from 10 to 15 seconds and again from 50 to 60 seconds?

bitrate missing in MediaFormat (Nexus 5 - Android 6.0.1)

Hi ๐Ÿ‘‹ ,

I've got this exception while testing with a Nexus 5 (Android 6.0.1)

E/Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android. java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference at android.media.MediaFormat.getInteger(MediaFormat.java:591) at com.otaliastudios.transcoder.strategy.DefaultAudioStrategy.getAverageInputBitRate(DefaultAudioStrategy.java:66) at com.otaliastudios.transcoder.strategy.DefaultAudioStrategy.createOutputFormat(DefaultAudioStrategy.java:39) at com.otaliastudios.transcoder.engine.Engine.computeTrackStatus(Engine.java:128) at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:309) at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:121) at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:111) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)

I had the chance to debug it and I found that the mediaformat map doesn't have any bitrate key, which is causing the issue. I tested with another device and everything is good. Can we have a default bitrate in this case?

mediaformat map:

"max-input-size" -> {Integer@4429} 355
"aac-profile" -> {Integer@4431} 2
"mime" -> "audio/mp4a-latm"
"durationUs" -> {Long@4435} 43733333
"csd-0" -> {ByteArrayBuffer@4437} "java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2]"
"channel-count" -> {Integer@4439} 1
"sample-rate" -> {Integer@4441} 48000

Exception on video taken with Snapchat

Transcoding always fail with this particular video from snapchat (don't have another sample)? File is 418KB. I've tried on 4 different devices and the problem is the same. Using v0.8.0 Maybe linked to #15 ?
This is my config:

val mTranscodeVideoStrategy = DefaultVideoStrategy.Builder()
    .bitRate(3000000.toLong())
    .addResizer(AtMostResizer(720, 1280))
    //.addResizer(ExactResizer(Size(720, 1280)))
    .build()

Transcoder
    .into(compressedFilePath)
    .setValidator(WriteVideoValidator())
    .setVideoTrackStrategy(mTranscodeVideoStrategy)
    .addDataSource(content.contentURL!!)
    .setListener(this@CompressFileWorker).transcode()
    .get()

I've tried without .bitRate() and the result is the same. Somehow I'm using the validator the wrong way since the file is already compressed and below my threshold.
Here is the errorlog:

2020-02-20 17:02:20.399 7850-8017/com.myapp.android W/FileSource: offset/length adjusted from 0/576460752303423487 to 0/427512
2020-02-20 17:02:20.413 7850-8017/com.myapp.android I/DefaultVideoStrategy: Input width&height: 360x716
2020-02-20 17:02:20.413 7850-8017/com.myapp.android I/DefaultVideoStrategy: Output width&height: 360x716
2020-02-20 17:02:20.414 7850-8017/com.myapp.android V/Engine: Duration (us): 5998000
2020-02-20 17:02:20.414 7850-8017/com.myapp.android V/Engine: new step: 0
2020-02-20 17:02:20.416 7850-8017/com.myapp.android E/Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android.
    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
        at com.otaliastudios.transcoder.source.DefaultDataSource.selectTrack(DefaultDataSource.java:64)
        at com.otaliastudios.transcoder.engine.Engine.openCurrentStep(Engine.java:149)
        at com.otaliastudios.transcoder.engine.Engine.getCurrentTrackTranscoder(Engine.java:219)
        at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:366)
        at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:134)
        at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:124)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        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:764)

I think somehow it seems no tracks are set but tbh couldn't figure out the exact problem by myself. You can download the file here: https://drive.google.com/open?id=1Jcwu2ryTyEwv5eWgUzZGA_kdHJ_KUhjD

writeSampleData returned an error

I am not able to merge video and audio, while doing so I got this error in the mid of the process.

W/DefaultDataSink: Failed to release the muxer.
java.lang.IllegalStateException: Failed to stop the muxer
at android.media.MediaMuxer.nativeStop(Native Method)
at android.media.MediaMuxer.stop(MediaMuxer.java:245)
at android.media.MediaMuxer.release(MediaMuxer.java:485)
at com.otaliastudios.transcoder.sink.DefaultDataSink.release(DefaultDataSink.java:206)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:394)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:150)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:140)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

E/Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android.
java.lang.IllegalStateException: writeSampleData returned an error
at android.media.MediaMuxer.nativeWriteSampleData(Native Method)
at android.media.MediaMuxer.writeSampleData(MediaMuxer.java:473)
at com.otaliastudios.transcoder.sink.DefaultDataSink.writeTrack(DefaultDataSink.java:151)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.drainEncoder(BaseTrackTranscoder.java:288)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.transcode(BaseTrackTranscoder.java:163)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:373)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:150)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:140)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

Error when concat multipe audio

Transcoder.into(path!!)
.addDataSource(pathAudio1) // or...
.addDataSource(pathAudio2) // or...
.setListener(object : TranscoderListener {
override fun onTranscodeCompleted(successCode: Int) {
Log.d("Process: ", "onTranscodeCompleted")
}

            override fun onTranscodeProgress(progress: Double) {
                Log.d("Process: ", "${progress}")
            }

            override fun onTranscodeCanceled() {
                Log.d("Process: ", "onTranscodeCanceled")
            }

            override fun onTranscodeFailed(exception: Throwable) {
                Log.d("Process: ", "onTranscodeFailed ${exception.message}")
            }

        }).transcode()

Result message:
onTranscodeFailed: More than one source selected for type VIDEO, but getTrackFormat returned null.

Reduce time: Compression taking time ~3 mins

Device: Nokia 5
Library version - 0.9.0

Video1: 3:42 mins, 552 MB
Video2: 4 mins, 17 MB
Video3: 2 mins, 13 MB

@natario1 The compression for the video file is working great.
However, all videos, individually, are taking a minimum of 3 mins for compression to complete.

Here's the code I am using for compression:

 public static DefaultVideoStrategy for360x480() {
        return DefaultVideoStrategy.exact(360, 480)
                .bitRate(500L * 1000)
                .frameRate(20)
                .keyFrameInterval(2F)
                .build();
    }
 mTranscodeAudioStrategy = DefaultAudioStrategy.builder()
                .channels(1)
                .bitRate(16000)
                .build();
    Transcoder.into(destPath)
            .addDataSource(filePath) // or...
            .setAudioTrackStrategy(mTranscodeAudioStrategy)
            .setVideoTrackStrategy(DefaultVideoStrategies.for360x480())
            .setListener(new TranscoderListener() {
                public void onTranscodeProgress(double progress) {
                    Log.i(TAG, "onTranscodeProgress: "+progress);
                }
                public void onTranscodeCompleted(int successCode) {
                    Log.i(TAG, "onTranscodeCompleted: "+successCode);
                }
                public void onTranscodeCanceled() {
                    Log.i(TAG, "onTranscodeCanceled: ");
                }
                public void onTranscodeFailed(@NonNull Throwable exception) {
                    exception.printStackTrace();
                }
            }).transcode();

Hooking between the decoder and encoder to manipulate the raw (audio) data

We would like to change the volume of a specific data source and then possibly mix it with another data source.

It would optimal for us to be able to do it during the transcoding process and the transcoder even has the raw audio data that can could be easily manipulated to change the volume (in AudioEngine.process)

Only few frames get converted. Need Support for Webm VP9 codec. [ Attached source file]

I have Webm video generated using webRTC. While converting process got completed immediately without progress bar reaching 100%. Output video length is 1 sec.
If i replace audio in transcoder full video get converted but in output same 1 sec is playing and frame freezes for remaining duration.

I have attached source file, please check it
Webm VP9 Video.zip

I have tried many Webm codec VP8, VP9, H264, etc ...

Few thing i have noticed are

  1. it works in emulator but when i run in my phone (Android 9) it does not work
  2. In Android 10, Webm file is not visible in file picker so cannot select the video.

Please help me, i need to complete this project in 2 days.

Fatal error while transcoding, this might be invalid format or bug in engine or Android.

E/MediaCodec: Codec reported err 0xffffec77, actionCode 0, while in state 3

E/MediaCodec: configure failed with err 0xffffec77, resetting...

E/Transcoder: Fatal error while transcoding, this might be invalid format or bug in engine or Android.
android.media.MediaCodec$CodecException: Error 0xffffec77
at android.media.MediaCodec.native_configure(Native Method)
at android.media.MediaCodec.configure(MediaCodec.java:1960)
at android.media.MediaCodec.configure(MediaCodec.java:1889)
at com.otaliastudios.transcoder.transcode.VideoTrackTranscoder.onConfigureDecoder(VideoTrackTranscoder.java:105)
at com.otaliastudios.transcoder.transcode.BaseTrackTranscoder.setUp(BaseTrackTranscoder.java:75)
at com.otaliastudios.transcoder.engine.Engine.openCurrentStep(Engine.java:194)
at com.otaliastudios.transcoder.engine.Engine.getCurrentTrackTranscoder(Engine.java:223)
at com.otaliastudios.transcoder.engine.Engine.transcode(Engine.java:371)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:150)
at com.otaliastudios.transcoder.Transcoder$1.call(Transcoder.java:140)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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:764)
E/Transcodeย Failed: Error 0xffffec77

Device: Samsung J8

OS: 9 Pie
If video is below 10 seconds then it get compressed.
if (video is portrait)
atMost =540
else
atMost = 304

val strategy = DefaultVideoStrategy.Builder()
.addResizer(AtMostResizer(atMost))
.bitRate(1700000)
.frameRate(30)
.build()

Transcoder.into("output Path")
.addDataSource("input path")
.setVideoTrackStrategy(strategy)
.setListener(this).transcode()

trim not working exactly

Like i trim for 0 to 60 second and after trim a video i got the video having 0 to 69 seconds.
so not accurate.

If you find any answer let me know.
I am also working on this issue.

How do I compress a video

I have a video recorded from native camera on Redmi 7A
For 10 secs video, the size is 25 MB.

I want to compress it without losing much video quality

I went through docs, but unable to find implementation flow.

PassThroughTrackTranscoder ignores original video rotation & value passed by setVideoRotation

Whenever transcoder engine uses PassThroughTrackTranscoder for video track, it ignores original video rotation metadata, and passed setVideoRotation value.

It seems library properly checks that the validator result should be ignored here, however, later it doesn't use this value, which results in a video without any rotation.

Sample code:

Transcoder
  .into(destinationPath)
  .addDataSource(new FilePathDataSource(sourcePath))
  .setVideoTrackStrategy(new PassThroughTrackStrategy())
  .setAudioTrackStrategy(new PassThroughTrackStrategy())
  .setVideoRotation(90)
  .transcode();

Also this code causes Transcoder to create a video without original rotation metadata:

Transcoder
  .into(destinationPath)
  .addDataSource(new FilePathDataSource(sourcePath))
  .setVideoTrackStrategy(new PassThroughTrackStrategy())
  .setAudioTrackStrategy(new RemoveTrackStrategy())
  .transcode();

Transcoder version: 0.9.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.