deepmedia / Transcoder

🎞 Hardware-accelerated video transcoding using Android MediaCodec APIs. Supports cropping, concatenation, clipping, audio processing, video speed and much more.
https://opensource.deepmedia.io/transcoder
Apache License 2.0
785 stars 167 forks source link

Support more than 2 audio channels #75

Open pawegio opened 4 years ago

pawegio commented 4 years ago

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)
natario1 commented 4 years ago

I think so, many components expect audio to be either 1 or 2 channels.

nafiskabbo commented 2 weeks ago

But when i try to compress some videos, it gets failed. What to do?

natario1 commented 2 weeks ago

Can you upload the file?

nafiskabbo commented 2 weeks ago

The vidoe link is "https://www.sample-videos.com/video321/mp4/720/big_buck_bunny_720p_30mb.mp4" The channel count shows as 6 as error

natario1 commented 2 weeks ago

Just released v0.11.2 with a fix. v0.11.2 allows videos with more than 2 channels, as you don't try to change the number of channels to something else (we still don't support downmix and upmix for 3+ channels).

Note, the fix does not work on on API23 emulator, I'm not sure whether it's emulator only or on real devices too. API24 and newer work well.

nafiskabbo commented 2 weeks ago

@natario1 Getting this. Any reason for it?

V/MediaMetadataRetriever( 7605): extractMetadata(9) I/Reader ( 7605): Returning State.Wait because source can't read VIDEO right now. I/VideoEncoder( 7605): Can't dequeue output buffer: INFO_TRY_AGAIN_LATER

natario1 commented 2 weeks ago

These logs are normal

nafiskabbo commented 2 weeks ago

I am uploading video after compression. Previous: This channel count 6 video was throwing error at first Now: It is running for infinite and never finishes.

natario1 commented 2 weeks ago

There's a test that transcodes this file successfully. What parameters are you using?

nafiskabbo commented 2 weeks ago

I am using default params mostly.

                        val videoTrackStrategy = DefaultVideoStrategy.Builder()
                                .keyFrameInterval(3f)
                                .bitRate(1280 * 720 * 4.toLong())
                                .frameRate(frameRate!!) // will be capped to the input frameRate
                                .build()

                audioTrackStrategy = if (includeAudio) {
                    val sampleRate = DefaultAudioStrategy.SAMPLE_RATE_AS_INPUT
                    val channels = DefaultAudioStrategy.CHANNELS_AS_INPUT

                    DefaultAudioStrategy.builder()
                        .channels(channels)
                        .sampleRate(sampleRate)
                        .build()
                } else {
                    RemoveTrackStrategy()
                }

                val dataSource = if (startTime != null || duration != null){
                    val source = UriDataSource(context, Uri.parse(path))
                    TrimDataSource(source, (1000 * 1000 * (startTime ?: 0)).toLong(), (1000 * 1000 * (duration ?: 0)).toLong())
                }else{
                    UriDataSource(context, Uri.parse(path))
                }

                transcodeFuture = Transcoder.into(destPath!!)
                        .addDataSource(dataSource)
                        .setAudioTrackStrategy(audioTrackStrategy)
                        .setVideoTrackStrategy(videoTrackStrategy)
                        .setListener(object : TranscoderListener {
                            override fun onTranscodeProgress(progress: Double) {
                                channel.invokeMethod("updateProgress", progress * 100.00)
                            }
                            override fun onTranscodeCompleted(successCode: Int) {
                                channel.invokeMethod("updateProgress", 100.00)
                                val json = Utility(channelName).getMediaInfoJson(context, destPath)
                                json.put("isCancel", false)
                                result.success(json.toString())
                                if (deleteOrigin) {
                                    File(path).delete()
                                }
                            }

                            override fun onTranscodeCanceled() {
                                result.success(null)
                            }

                            override fun onTranscodeFailed(exception: Throwable) {
                                result.success(null)
                            }
                        }).transcode()
natario1 commented 2 weeks ago

Maybe something is missing there. I'm using this code and it works (even without ClipDataSource):

val dataSource = input("bbb_720p_30mb.mp4")
val videoTrackStrategy = DefaultVideoStrategy.Builder()
    .keyFrameInterval(3f)
    .bitRate(1280 * 720 * 4.toLong())
    .frameRate(30)
    .build()
val audioTrackStrategy = DefaultAudioStrategy.builder()
    .channels(DefaultAudioStrategy.CHANNELS_AS_INPUT)
    .sampleRate(DefaultAudioStrategy.SAMPLE_RATE_AS_INPUT)
    .build()
addDataSource(ClipDataSource(dataSource, 0, 5_000_000))
setAudioTrackStrategy(audioTrackStrategy)
setVideoTrackStrategy(videoTrackStrategy)