Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc? (Read 13553 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Hi. I'm trying to convert TRUEHD 7.1 audio to Opus 5.1 using the recommended bitrate of 256 kb/s (should be enough right)

The issue is that if I don't use 
Code: [Select]
--raw --raw-chan 6
I get the error:

Code: [Select]
Error parsing input file: file.eng.thd

Why? Am I doing something wrong? I use ffmpeg to copy the audio stream from the file. My full opusenc command:

Code: [Select]
opusenc --bitrate 256 --vbr --comp 10 file.eng.thd test.opus

I have a few more questions...

2) What does `6 coupled, 2 uncoupled` means?
3) If I set the bitrate to 384 to Opus 7.1 why it goes as high as 744kbit/s? Isn't that a bit excessive?
4) How can the difference between the 5.1 and 7.1 audio be only 30 MB?

EDIT:

I just heard the audios and they are only noise, like the old tv's when they couldn't find a channel? I don't know the right words in english...but it's garbage :(
 

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #1
You first need to decode thd to wav and mix somehow 7.1 to 5.1.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #2
Why? Am I doing something wrong?
You need to convert the audio to a format opusenc recognizes, like as WAV with uncompressed PCM. Copying the audio stream won't work. (This is why the audio sounds like TV static.)

Also, if you want 5.1 audio, you'll need to downmix somehow.

I believe ffmpeg can do both of these things.

2) What does `6 coupled, 2 uncoupled` means?
Two channels of audio can be compressed into a single Opus stream to improve efficiency by allowing them to share data when both channels are similar. This means your 7.1 audio (which has 8 channels) is being compressed to 5 Opus streams.

3) If I set the bitrate to 384 to Opus 7.1 why it goes as high as 744kbit/s? Isn't that a bit excessive?
No. You're encoding in VBR mode, which means opusenc is aiming for a specific quality level. The bitrate will change to meet that quality level. If you encode a whole lot of different audio with those settings, the average bitrate will be 384kbps, but individual clips can be much higher or much lower.

4) How can the difference between the 5.1 and 7.1 audio be only 30 MB?
You're encoding TV static, so your results will not be normal.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #3
You can use Eac3to to convert dd truehd to opus.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #4
With ffmpeg and libopus you could try:
Code: [Select]
ffmpeg -i file.eng.thd -c:a libopus -b:a 256000 -ac 6 -mapping_family 1 -apply_phase_inv 0

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #5
You can use Eac3to to convert dd truehd to opus.

I need linux command line tools only

With ffmpeg and libopus you could try:
Code: [Select]
ffmpeg -i file.eng.thd -c:a libopus -b:a 256000 -ac 6 -mapping_family 1 -apply_phase_inv 0


Is there any benefit in using ffmpeg over opusenc? I was looking for opusenc specifically to be sure I'm using the latest implementation - instead of relying on my possible outdated ffmpeg.

Why? Am I doing something wrong?
You need to convert the audio to a format opusenc recognizes, like as WAV with uncompressed PCM. Copying the audio stream won't work. (This is why the audio sounds like TV static.)


I understand. So opusenc only accept WAV as input? So how ffmpeg is able to process any audio input file to opus if opusenc itself can't?

Also I'm no linux expert, so could anyone help me adapt my script to deal with this? I'm trying to batch convert a lot of media, so I did a ffmpeg script that would extract the audio from all my files, and then I planned on using opusenc to convert it all to Opus. I would encode the video separately from the audio so I could have 4 video encodes running on a dedicated CPU + audio encodes in 1 CPU.

Because the way I see it now, my script just got a lot harder - I can't just copy all audio streams and feed them to opusenc, now I have to detect and convert to a lossless format all the codecs opusenc doesn't support.

Or I could use ffmpeg to do this but then i think it would be even harder - I only want to encode the highest quality english audio track + a portuguese audio track if present to opus 5.1 while also discarding the video, since I'll encode the video in batch separated from the audio streams...

Here is my code:  https://github.com/Nottt/Scripts/blob/master/audio/get-audio.sh

My end goal here is to have a script that can just extract audio to convert to opus 5.1, while another script is converting the video in parallel so I can use 100% of my CPU cores and in the end I just merge the files.

Thank you all! :D

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #6
Well, actually it would be harder to do everything step by step as opusenc cannot decode nor downmix to 5.1.

In your script you could just replace the extract with the actual complete encoding, e.g.
Code: [Select]
# Extract them 
ffmpeg -i "$1" -c:a:0 copy "${1%.mkv}"."$AUDIO_LANG"."$AUDIO_CODEC"
to
Code: [Select]
# Extract them 
ffmpeg -i "$1" -c:a:0 libopus -b:a 256000 -ac 6 -mapping_family 1 -apply_phase_inv 0 "${1%.mkv}"."$AUDIO_LANG".opus
and respectively for the other tracks, too. That way get the complete audio you desire with the script of yours without any further work (at least if your desired audio tracks are the first two audio tracks ;) ). You propably don't neet the "## Fix TRUEHD" error handling either.

With that your audio conversion is only one track at a time and not all at once but i guess it doesn't matter much as the video encoding will be your limiting factor.

As for the used libopus library you would have to check your linux distribution documentation I guess.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #7
Well, actually it would be harder to do everything step by step as opusenc cannot decode nor downmix to 5.1.

Thanks but I still do not understand... How can ffmpeg encode any input to opus but opusenc can't?


Code: [Select]
# Extract them 
ffmpeg -i "$1" -c:a:0 libopus -b:a 256000 -ac 6 -mapping_family 1 -apply_phase_inv 0 "${1%.mkv}"."$AUDIO_LANG".opus

As for the used libopus library you would have to check your linux distribution documentation I guess.

Thanks I just have a few more questions...

1) Is this ffmpeg command same quality as running opusenc with --vbr --bitrate 256 --comp 10?
2) What if I wanted to keep 7.1 audio?
3) What happens if the input isn't 5.1 audio? Guess I'd have to create some logic to make 2.0 input be encoded to 2.0 but just to make sure
4) The ffmpeg I use is this PPA with ubuntu 16.04...  I think that is the easiest way to keep yourself updated with ffmpeg but don't know how to check if I'm truly using the latest libopus release

I researched your command and I see this:

Quote
mapping_family (mapping_family)
Set channel mapping family to be used by the encoder. The default value of -1 uses mapping family 0 for mono and stereo inputs, and mapping family 1 otherwise. The default also disables the surround masking and LFE bandwidth optimzations in libopus, and requires that the input contains 8 channels or fewer.

Other values include 0 for mono and stereo, 1 for surround sound with masking and LFE bandwidth optimizations, and 255 for independent streams with an unspecified channel layout.

So if I'm reading it right, it shouldn't be needed to use it since the default is 0 for mono and stero inputs and 1 otherwise?

Thanks  :D

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #8
Thanks but I still do not understand... How can ffmpeg encode any input to opus but opusenc can't?
opusenc has limited decoding capability, so it really only supports raw PCM formats in WAV format, or raw PCM data.

FFmpeg, being a gigantic collection of encoders and decoders, is capable of directly converting a whole mess of formats from one to the other, and also includes filters for manipulating the data in the process, if necessary.

Really, if opusenc were to support literally every input format you could imagine, it may as well just import FFmpeg to handle input formats. And at that point, you're basically reimplementing the official FFmpeg frontend for little gain.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #9
Quote
So if I'm reading it right, it shouldn't be needed to use it since the default is 0 for mono and stero inputs and 1 otherwise?
Well, actually I wasn't sure as it also says "The default also disables the surround masking and LFE bandwidth optimzations in libopus". So I wanted to be sure that the optimizations are on and set it manually.
Quote
1) Is this ffmpeg command same quality as running opusenc with --vbr --bitrate 256 --comp 10?
Yes, it's basically the same as vbr and comp 10 are the defaults in ffmpeg and libopus.
Quote
2) What if I wanted to keep 7.1 audio?
The -ac command defines the output audio channels. If the source has a different number of channels it will mix to the desired number. So if you have 7.1 input and would want to keep it you can omit the option or set -ac 8 (-ac 2 mixes down to stereo).
Quote
3) What happens if the input isn't 5.1 audio? Guess I'd have to create some logic to make 2.0 input be encoded to 2.0 but just to make sure
As said above it would just up or downmix to 5.1. And yes, you need some logic for that as you cannot specify the bitrate per channel. You could omit the -ac to keep the original number of channels but you would also end up with the same bitrate no matter if stereo or 7.1 so you have to change your script accordingly.
Quote
4) The ffmpeg I use is this PPA with ubuntu 16.04...  I think that is the easiest way to keep yourself updated with ffmpeg but don't know how to check if I'm truly using the latest libopus release
I'm sorry, I don't know much about the Ubuntu package management but if I understand the link correctly then your source does not contain libopus. I'm not sure. If it doesn't (you get an error trying to convert with -c:a: libopus) you could:
1: pipe the decoded stream to opusenc (I'm not that fit with linux pipes)
2: save the decoded stream as wav or flac and encode that with opusenc
Code: [Select]
ffmpeg -i "$1" -c:a:0 flac -ac 6  "${1%.mkv}"."$AUDIO_LANG".flac
3: manually download a ffmpeg binary with static libraries including libopus that is up to date ( https://www.johnvansickle.com/ffmpeg/ )

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #10
Thank you all guys <3


Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #11
Hi all
When I began to use Opus for encoding 2.0 - 7.1 channel files, I struggled with these and other problems like correct channel-mapping etc. too. So I made a short guide for me which worked so far.
The commands here where all used with a windows environment and FFmpeg and Opus together in a pipe. It shouldn't be a big deal to use it the same way with Linux. The meaning of the values like bitrate, sampling rate etc. should be self-explanatory.
Hope this can help a little bit.  :)

FFmpeg and Opus Audio Codec (16bit, 48kHz)
- Opus is a 48kHz-only format. Other input-samplerates will be internaly converted, using an internal *Speex* resampler.
- Input bitdepth for Opus is 16bit.
- FFmpeg has an internal Opus encoder. You can use this if you want.
- If FFmpeg is a part of a pipe, you have to organise the audio channel-mapping on your own. <br>Otherwise: Output order = Input Order
- Depending on the input, sometimes you have to use the "BL" & "BR" Channels instead "SL" & "SR". <br>But it doesn't matter if you use "...c3=SL+BL|c4=SR+BR...".
- Channel Description:
  - FL: Front Left, FC: Front Center, FR: Front Right
  - SL: Side Left, SR: Side Right
  - BL: Back Left, BR: Back Right (Also known as "Rear" instead of "Back")
  - SL: Side Left, SR: Side Right
  - LFE: Low Frequency Effects

- Opus channel mappings
    - 1 channel: monophonic (mono).
    - 2 channels: stereo (FL, FR).
    - 3 channels: linear surround (FL, FC, FR).
    - 4 channels: quadraphonic (FL, FR | BL, BR).
    - 5 channels: 5.0 surround (FL, FC, FR | BL, BR).
    - 6 channels: 5.1 surround (FL, FC, FR | BL, BR | LFE).
    - 7 channels: 6.1 surround (FL, FC, FR | SL, SR | BC | LFE).
    - 8 channels: 7.1 surround (FL, FC, FR | SL, SR | BL, BR | LFE).
    - Source

1. Convert a 16bit 5.1 audiofile to ~512kbps Opus with "opusenc.exe":
Code: [Select]
"ffmpeg.exe" -i "input.ac3" -af "pan=0x3f|c0=FL|c1=FC|c2=FR|c3=SL+BL|c4=SR+BR|c5=LFE" -f s16le -ac 6 - | "opusenc.exe" - --raw --raw-chan 6 --raw-bits 16 --vbr --bitrate 512 --comp 10 --expect-loss 0 "output.opus"

2. Convert a 24bit 5.1 audiofile to ~512kbps Opus with "opusenc.exe":
Code: [Select]
"ffmpeg.exe" -i "input.dts" -af "aresample=resampler=soxr:dither_method=shibata,aformat=sample_fmts=s16,pan=0x3f|c0=FL|c1=FC|c2=FR|c3=SL+BL|c4=SR+BR|c5=LFE" -f s16le -ac 6 - | "opusenc.exe" - --raw --raw-chan 6 --raw-bits 16 --vbr --bitrate 512 --comp 10 --expect-loss 0 "output.opus"

3. Convert a 24bit 6.1 audiofile to ~512kbps Opus with "opusenc.exe":
Code: [Select]
"ffmpeg.exe" -i "input.dts" -af "aresample=resampler=soxr:dither_method=shibata,aformat=sample_fmts=s16,pan=6.1(back)|c0=FL|c1=FC|c2=FR|c3=SL+BL|c4=SR+BR|c5=BC|c6=LFE" -f s16le -ac 7 - | "opusenc.exe" - --raw --raw-chan 7 --raw-bits 16 --vbr --bitrate 512 --comp 10 --expect-loss 0 "output.opus"

4. Convert a 24bit 7.1 audiofile to ~512kbps Opus with "opusenc.exe":
Code: [Select]
"ffmpeg.exe" -i "input.dts" -af "aresample=resampler=soxr:dither_method=shibata,aformat=sample_fmts=s16,pan=0x63f|c0=FL|c1=FC|c2=FR|c3=SL|c4=SR|c5=BL|c6=BR|c7=LFE" -f s16le -ac 8 - | "opusenc.exe" - --raw --raw-chan 8 --raw-bits 16 --vbr --bitrate 512 --comp 10 --expect-loss 0 "output.opus"


Other FFmpeg examples
- If you lower the bitdepth from 24bit to 16bit, use dither.
- "-map" let you select the required audiostream. <br>

1. Extract a 16bit, 5.1 audiostream from a m2ts-File to 16bit WAV:
Code: [Select]
"ffmpeg.exe" -i "input.m2ts" -c:a pcm_s16le -map 0:a:4 -ac 6 -rf64 auto "output.wav"

2. Extract a 24bit, 7.1 audiostream from a m2ts-File to 24bit WAV:
Code: [Select]
"ffmpeg.exe" -i "input.m2ts" -c:a pcm_s24le -map 0:a:2 -ac 8 -rf64 auto "output.wav"

3. Extract a 24bit 192kHz, 7.1 audiostream from a m2ts-File to 16bit 48kHz WAV:
Code: [Select]
"ffmpeg.exe" -i "input.m2ts" -c:a pcm_s16le -af "aresample=resampler=soxr:osr=48000:dither_method=shibata,aformat=sample_fmts=s16" -map 0:a:1 -ac 8 -rf64 auto "output.wav"

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #12
Code: [Select]
"ffmpeg.exe" -i "input.dts" -af "aresample=resampler=soxr:dither_method=shibata,aformat=sample_fmts=s16,pan=0x3f|c0=FL|c1=FC|c2=FR|c3=SL+BL|c4=SR+BR|c5=LFE" -f s16le -ac 6 - | "opusenc.exe" - --raw --raw-chan 6 --raw-bits 16 --vbr --bitrate 512 --comp 10 --expect-loss 0 "output.opus"

But he explicitly wanted linux not windows. So something like this would be better:

Code: [Select]
ffmpeg -i input.dts -af aresample=resampler=soxr:dither_method=shibata,aformat=sample_fmts=s16,pan="0x3f|c0=FL|c1=FC|c2=FR|c3=SL+BL|c4=SR+BR|c5=LFE" -f s16le -ac 6 - | opusenc - --raw --raw-chan 6 --raw-bits 16 --vbr --bitrate 512 --comp 10 --expect-loss 0 output.opus

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #13
Doesn't opusenc support raw normalized floating point input?

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #14
Doesn't opusenc support raw normalized floating point input?

Should do.  WFM, but I've only ever tested with two channels.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #15
If you want to encode opus directly from ffmpeg, not using opusenc, you have to use some weird options because the defaults are broken.

Code: [Select]
ffmpeg -i input.mkv -af aformat=channel_layouts="7.1|5.1|stereo" -mapping_family 1 -vcodec copy -scodec copy -acodec libopus -map 0 output.mkv

Without the channel_layouts stuff, ffmpeg will fail with an error such as "Invalid channel layout 5.1(side) for specified mapping family -1". Without the mapping_family option, ffmpeg will disable channel coupling and LFE optimization.

The default bitrate is 96k for stereo, 320k for 5.1, and 416k for 7.1. There's no way to change this in a sensible way (e.g. per channel); if you set a bitrate it will apply the same rate to stereo, 5.1, 7.1, etc.

Re: How to encode TRUEHD 5.1 to Opus 5.1 using opusenc?

Reply #16
If you want to encode opus directly from ffmpeg, not using opusenc, you have to use some weird options because the defaults are broken.

Code: [Select]
ffmpeg -i input.mkv -af aformat=channel_layouts="7.1|5.1|stereo" -mapping_family 1 -vcodec copy -scodec copy -acodec libopus -map 0 output.mkv

Without the channel_layouts stuff, ffmpeg will fail with an error such as "Invalid channel layout 5.1(side) for specified mapping family -1". Without the mapping_family option, ffmpeg will disable channel coupling and LFE optimization.

The default bitrate is 96k for stereo, 320k for 5.1, and 416k for 7.1. There's no way to change this in a sensible way (e.g. per channel); if you set a bitrate it will apply the same rate to stereo, 5.1, 7.1, etc.


How can I know if my files have channel coupling and LFE optimization after they are encoded?