Multiple audio tracks with different codecs and languages

All about user-defined episode / movie / file name format expressions
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

@Kim, It is not new as they report MLP FBA 16-ch in the codec, it's short for Meridian Lossless Packing with FBA stream, it did however change in the fact that this is not reported in common fields by MediaInfo
I only work in black and sometimes very, very dark grey. (Batman)
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

By the way, I'm not exactly sure if they were already present or were added in more recent versions, however now the {channel} and {aco} bindings are fairly similar to the script.
I'm fairly confident it could be significantly simplified, will post some results.
I only work in black and sometimes very, very dark grey. (Batman)
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

As you can see some bindings are broken with the new MediaInfo

DTS:X
Before:
{ac}=DTS
{aco}= Binding "aco": undefined
{af}=6ch (Wrong)
{channels}=7.1
Format DTS
Format_Commercial DTS
Channel(s) Object Based / 8 / 6
ChannelPositions/String2 Object Based / 3/2/2.1 / 3/2/0.1
CodecID A_DTS
old: Codec DTS-HD
old: Format_Profile X / MA / Core

After:
{ac}=DTS
{aco}= Binding "aco": undefined
{channels}= Binding "channels": No value present
{af}=Binding "af": No value present
Format DTS
Format_Commercial DTS-HD Master Audio
Channel(s) 8
ChannelPositions/String2 Object Based
CodecID A_DTS
new: Format/String DTS XLL X
new: Format_AdditionalFeatures XLL X
****************************************************************************

TrueHD:
Before:
{ac}=TrueHD
{aco}= Binding "aco": undefined
{channels}=7.1
{af}=8ch
Format TrueHD
Format_Commercial TrueHD
ChannelPositions/String2 3/2/2.1
CodecID A_TRUEHD

After:
{ac}=MLPFBA
{aco}= Binding "aco": undefined
{channels}=7.1
{af}=8ch
Format MLP FBA
Format_Commercial Dolby TrueHD
ChannelPositions/String2 3/2/2.1
CodecID A_TRUEHD
****************************************************************************

TrueHD+Atmos:
Before:
{ac}=TrueHD
{aco}= TrueHD+Atmos
{channels}=7.1
{af}=8ch
Format TrueHD
Format_Commercial TrueHD
Format_Profile TrueHD+Atmos / TrueHD
ChannelPositions/String2 Object Based / 3/2/2.1
CodecID A_TRUEHD

After:
{ac}=MLPFBA
{aco}= Binding "aco": undefined
{channels}=7.1
{af}=8ch
Format MLP FBA
Format/String MLP FBA 16-ch
Format_Commercial Dolby TrueHD with Dolby Atmos
Format_AdditionalFeatures 16-ch
ChannelPositions/String2 3/2/2.1
CodecID A_TRUEHD
****************************************************************************
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

So, as MediaInfo changed a bit and I realized how I was needlessly trying to replicate the logic already present in MediaBindingBean.java this is a new version of the snippet

Code: Select all

// somewhere at the top 
import net.filebot.Language

      { // map Codec + Format Profile
        def mCFP = [
          "FLAC" : "FLAC",
          "PCM" : "PCM",
          "MP3": "MP3",
          "E-AC-3 JOC": "E-AC-3",
          "DTS ES XXCH": "DTS-ES Discrete",
          "MLP FBA": "TrueHD",
          "MLP FBA 16-ch": "TrueHD"
        ]
        audio.collect { au ->
          def ac1 = any{ au['CodecID/Hint'] }{au['Format/String']}{ au['Format'] } // extends _ac_ which strips spaces > "CodecID/Hint", "Format"
          def ac2 = any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] }
          def atmos = (aco =~ /(?i:atmos)/) ? 'Atmos' : null // _aco_ uses "Codec_Profile", "Format_Profile", "Format_Commercial"
          def combined = allOf{ac1}{ac2}.join(' ')
          def fallback = any{ac1}{ac2}{aco}
          def stream = allOf
            /* _channels_ as it uses "ChannelPositions/String2", "Channel(s)_Original", "Channel(s)"
               compared to _af_ which uses "Channel(s)_Original", "Channel(s)" */
            { allOf{"${channels}"}{au['NumberOfDynamicObjects'] + "obj"}.join('+') }
            { allOf{ mCFP.get(combined, aco) }{atmos}.join('+') } /* bit risky keeping aco as default */
            { Language.findLanguage(au['Language']).ISO3.upperInitial() }
            /* _cf_ not being used > "Codec/Extensions", "Format" */
          return stream
        }.sort{a, b -> a.first() <=> b.first() }*.join(" ").join(", ") }
Unfortunately most of the map is now a bit useless and I only left the ugly MLP FBA.
aco =~ /(?i:atmos)/ is being used as aco.match(/atmos/) fails with Pattern not found: Dolby TrueHD when the string isn't present.
Expected output is:
7.1+15obj TrueHD+Atmos for Dolby Amaze Atmos trailer
5.1 AC-3 for the Amaze regular trailer
5.1 DTS-HD MA Eng, 5.1 PCM Eng, 5.1 AC-3 Eng for Dolby 3D Glass Return Trailer
5.1+11obj E-AC-3+Atmos Eng for Dolby Natures Fury Atmos trailer

I tested it on MacOS, latest version of FileBot available.

Code: Select all

/Applications/FileBot.app//Contents/MacOS/libmediainfo.dylib:
	/usr/local/lib/libmediainfo.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
	/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 489.0.0)
not very informative as version unfortunately.
Feedback welcome.
I only work in black and sometimes very, very dark grey. (Batman)
User avatar
rednoah
The Source
Posts: 23469
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Multiple audio tracks with different codecs and languages

Post by rednoah »

1.
All versions of FileBot come packaged with the latest MediaInfo release, which is currently Version 18.12, but on Linux / Synology / etc FileBot may not package libmediainfo and instead rely on the one provided by your distribution packaging system.


2.
Here's how {aco} is currently implemented:
https://www.filebot.net/docs/api/src-ht ... l#line.414

:?: Any idea how to make it work with newer libmediainfo versions?
:idea: Please read the FAQ and How to Request Help.
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

I don't believe the issue it's not working, default bindings are slightly worse but there still is the option to access raw MediaInfo bindings.
These have shifted around it seems mainly with Codec bindings which now seem deprecated > Codec, Codec/String, Codec/Family, Codec/Info, Codec/Url and Codec_Profile https://github.com/MediaArea/MediaInfoLib/blob/29be23e7bc740e1ba39ce6a231ceb69c254b4401/Source/MediaInfo/MediaInfo_Config_Automatic.cpp#L4864

The nicest output is probably Format_Commercial when available, but it's usually quite verbose, for example in the Dolby Amaze trailer it outputs Dolby TrueHD with Dolby Atmos or something similar, and for DTS-HD MA it returns DTS-HD Master Audio.
I can't recall a single field consistently outputting nice info; all DTS have DTS as format, without distinguishing between variants, however DTS ES-Discrete is actually the commercial name for DTS ES with XCh/XXCh extension (vs DTS ES Matrix with no header).

First try, totally untested:

Code: Select all

af = getMediaInfo(StreamKind.Audio, 0, "Format/String", "Format"); // short version
ac = getMediaInfo(StreamKind.Audio, 0, "CodecID/Hint", "CodecID/String", "CodecID"); // not sure about Hint
afo = getMediaInfo(StreamKind.Audio, 0, "Format_AdditionalFeatures", "Matrix_Format"); // for additional format features (DTS Neural)
aco = getMediaInfo(StreamKind.Audio, 0, "Format_Profile", "Format_Commercial"); // nicelooking
However there are also some other bindings affected, for example the MediaInfo fields used for af used to contain object data, which are now separate, it seems that some relevant changes were introduced here https://github.com/MediaArea/MediaInfoLib/commit/e972a629ce7cbe6e110a0f8bde7c0c43850c0ad0
NumberOfDynamicObjects in Atmos.
I only work in black and sometimes very, very dark grey. (Batman)
User avatar
rednoah
The Source
Posts: 23469
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Multiple audio tracks with different codecs and languages

Post by rednoah »

Ideally, the top-level bindings take care of differences in underlying MediaInfo versions, so it'll just work regardless of MediaInfo version, as best as possible anyway.

I only have one test files for ATMOS, and none for DTS. So MediaInfo dumps + preferences for MI fields to base aco, channels, etc on are appreciated.

{aco} at least uses "Codec_Profile", "Format_Profile", "Format_Commercial" so at least the last one should work reasonably well with the latest release.

"Format_AdditionalFeatures", "Matrix_Format" I haven't really seen before. I guess I could add a binding if it's useful, are have af / channels check that field as well if that makes sense.
:idea: Please read the FAQ and How to Request Help.
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

How can I provide MediaInfo dumps? Meaning, which format, I don't believe MacOS version exports to anything else besides text, and a slew of XML formats.
By the way, the Dolby files are freely available on their website, in addition to those there are a few examples on https://streams.videolan.org/samples/ for all tastes.
I believe the most consistent across version is CodecID, which, however, isn't particularly pleasing (it usually has A_<codecname> and is allcaps)
Also which kind of output should I aim for to keep compatibility?
I only work in black and sometimes very, very dark grey. (Batman)
User avatar
rednoah
The Source
Posts: 23469
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Multiple audio tracks with different codecs and languages

Post by rednoah »

You can view all the MediaInfo tables for each stream via FileBot:
viewtopic.php?f=5&t=4285

You can CTRL+A / CTRL+C to copy & paste a relevant table.
:idea: Please read the FAQ and How to Request Help.
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

4.8.5 on MacOS

DTS HD MA

Code: Select all

Format	DTS
Format/String	DTS XLL
Format/Info	Digital Theater Systems
Format/Url	https://en.wikipedia.org/wiki/DTS_(sound_system)
Format_Commercial	DTS-HD Master Audio
Format_Commercial_IfAny	DTS-HD Master Audio
Format_Settings_Mode	16
Format_Settings_Endianness	Big
Format_AdditionalFeatures	XLL
CodecID	A_DTS
Duration	29536
Duration/String	29 s 536 ms
Duration/String1	29 s 536 ms
Duration/String2	29 s 536 ms
Duration/String3	00:00:29.536
Duration/String5	00:00:29.536
BitRate_Mode	VBR
BitRate_Mode/String	Variable
Channel(s)	6
Channel(s)/String	6 channels
ChannelPositions	Front: L C R, Side: L R, LFE
ChannelPositions/String2	3/2/0.1
ChannelLayout	C L R Ls Rs LFE
SamplesPerFrame	512
SamplingRate	48000
SamplingRate/String	48.0 kHz
FrameRate	93.750
FrameRate/String	93.750 FPS (512 SPF)
BitDepth	24
BitDepth/String	24 bits
Compression_Mode	Lossless
Compression_Mode/String	Lossless
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	0
Video_Delay/String3	00:00:00.000
Title	DTS-HD MA 5.1
Language	en
Language/String	English
Language/String1	English
Language/String2	en
Language/String3	eng
Language/String4	en
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
DTS-HD HR

Code: Select all

Format	DTS
Format/String	DTS XBR
Format/Info	Digital Theater Systems
Format/Url	https://en.wikipedia.org/wiki/DTS_(sound_system)
Format_Commercial	DTS-HD High Resolution Audio
Format_Commercial_IfAny	DTS-HD High Resolution Audio
Format_Settings_Mode	16
Format_Settings_Endianness	Big
Format_AdditionalFeatures	XBR
CodecID	A_DTS
Duration	16246
Duration/String	16 s 246 ms
Duration/String1	16 s 246 ms
Duration/String2	16 s 246 ms
Duration/String3	00:00:16.246
Duration/String5	00:00:16.246
BitRate_Mode	CBR
BitRate_Mode/String	Constant
BitRate	3018000
BitRate/String	3 018 kb/s
Channel(s)	6
Channel(s)/String	6 channels
Channel(s)_Original	8
Channel(s)_Original/String	8 channels
ChannelPositions	Front: L C R, Side: L R, Back: L R, LFE
ChannelPositions/String2	3/2/2.1
ChannelLayout	C L R LFE Lb Rb Lss Rss
SamplesPerFrame	512
SamplingRate	96000
SamplingRate/String	96.0 kHz
FrameRate	187.500
FrameRate/String	187.500 FPS (512 SPF)
BitDepth	24
BitDepth/String	24 bits
Compression_Mode	Lossy
Compression_Mode/String	Lossy
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	0
Video_Delay/String3	00:00:00.000
StreamSize	6128803
StreamSize/String	5.84 MiB (25%)
StreamSize/String1	6 MiB
StreamSize/String2	5.8 MiB
StreamSize/String3	5.84 MiB
StreamSize/String4	5.845 MiB
StreamSize/String5	5.84 MiB (25%)
StreamSize_Proportion	0.24785
Language	en
Language/String	English
Language/String1	English
Language/String2	en
Language/String3	eng
Language/String4	en
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
DTS:X

Code: Select all

OriginalSourceMedium_ID	4352
OriginalSourceMedium_ID/String	4352 (0x1100)
Format	DTS
Format/String	DTS XLL X
Format/Info	Digital Theater Systems
Format/Url	https://en.wikipedia.org/wiki/DTS_(sound_system)
Format_Commercial	DTS-HD Master Audio
Format_Commercial_IfAny	DTS-HD Master Audio
Format_Settings_Mode	16
Format_Settings_Endianness	Big
Format_AdditionalFeatures	XLL X
CodecID	A_DTS
Duration	18944.000000
Duration/String	18 s 944 ms
Duration/String1	18 s 944 ms
Duration/String2	18 s 944 ms
Duration/String3	00:00:18.944
Duration/String4	00:00:18:84
Duration/String5	00:00:18.944 (00:00:18:84)
BitRate_Mode	VBR
BitRate_Mode/String	Variable
BitRate	6089277
BitRate/String	6 089 kb/s
Channel(s)	8
Channel(s)/String	8 channels
Channel(s)_Original	Object Based
Channel(s)_Original/String	Object Based
ChannelPositions	Object Based
ChannelPositions/String2	Object Based
ChannelLayout	Object Based
SamplesPerFrame	512
SamplingRate	48000
SamplingRate/String	48.0 kHz
FrameRate	93.750
FrameRate/String	93.750 FPS (512 SPF)
BitDepth	24
BitDepth/String	24 bits
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	0
Video_Delay/String3	00:00:00.000
StreamSize	14419408
StreamSize/String	13.8 MiB (18%)
StreamSize/String1	14 MiB
StreamSize/String2	14 MiB
StreamSize/String3	13.8 MiB
StreamSize/String4	13.75 MiB
StreamSize/String5	13.8 MiB (18%)
StreamSize_Proportion	0.17777
Title	Surround 7.1
Language	en
Language/String	English
Language/String1	English
Language/String2	en
Language/String3	eng
Language/String4	en
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
OriginalSourceMedium	Blu-ray
Dolby TrueHD + Atmos

Code: Select all

Format	MLP FBA
Format/String	MLP FBA 16-ch
Format/Info	Meridian Lossless Packing FBA with 16-channel presentation
Format_Commercial	Dolby TrueHD with Dolby Atmos
Format_Commercial_IfAny	Dolby TrueHD with Dolby Atmos
Format_AdditionalFeatures	16-ch
CodecID	A_TRUEHD
CodecID/Url	http://www.dolby.com/consumer/technology/trueHD.html
Duration	63500.000000
Duration/String	1 min 3 s
Duration/String1	1 min 3 s 500 ms
Duration/String2	1 min 3 s
Duration/String3	00:01:03.500
Duration/String5	00:01:03.500
BitRate_Mode	VBR
BitRate_Mode/String	Variable
BitRate	6693961
BitRate/String	6 694 kb/s
BitRate_Maximum	9096000
BitRate_Maximum/String	9 096 kb/s
Channel(s)	8
Channel(s)/String	8 channels
ChannelPositions	Front: L C R, Side: L R, Back: L R, LFE
ChannelPositions/String2	3/2/2.1
ChannelLayout	L R C LFE Ls Rs Lb Rb
SamplesPerFrame	40
SamplingRate	48000
SamplingRate/String	48.0 kHz
FrameRate	1200.000
FrameRate/String	1 200.000 FPS (40 SPF)
Compression_Mode	Lossless
Compression_Mode/String	Lossless
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	0
Video_Delay/String3	00:00:00.000
StreamSize	53133320
StreamSize/String	50.7 MiB (36%)
StreamSize/String1	51 MiB
StreamSize/String2	51 MiB
StreamSize/String3	50.7 MiB
StreamSize/String4	50.67 MiB
StreamSize/String5	50.7 MiB (36%)
StreamSize_Proportion	0.36310
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
NumberOfDynamicObjects	15
BedChannelCount/String	1 channel
BedChannelConfiguration	LFE
Dolby Digital Plus + Atmos

Code: Select all

Format	E-AC-3
Format/String	E-AC-3 JOC
Format/Info	Enhanced AC-3 with Joint Object Coding
Format/Url	https://en.wikipedia.org/wiki/Dolby_Digital_Plus
Format_Commercial	Dolby Digital Plus with Dolby Atmos
Format_Commercial_IfAny	Dolby Digital Plus with Dolby Atmos
Format_Settings_Endianness	Big
Format_AdditionalFeatures	JOC
InternetMediaType	audio/eac3
CodecID	A_EAC3
Duration	110944.000000
Duration/String	1 min 50 s
Duration/String1	1 min 50 s 944 ms
Duration/String2	1 min 50 s
Duration/String3	00:01:50.944
Duration/String4	00:01:51:26
Duration/String5	00:01:50.944 (00:01:51:26)
BitRate_Mode	CBR
BitRate_Mode/String	Constant
BitRate	448000
BitRate/String	448 kb/s
Channel(s)	6
Channel(s)/String	6 channels
ChannelPositions	Front: L C R, Side: L R, LFE
ChannelPositions/String2	3/2/0.1
ChannelLayout	L R C LFE Ls Rs
SamplesPerFrame	1536
SamplingRate	48000
SamplingRate/String	48.0 kHz
FrameRate	31.250
FrameRate/String	31.250 FPS (1536 SPF)
Compression_Mode	Lossy
Compression_Mode/String	Lossy
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	-67
Video_Delay/String	-67 ms
Video_Delay/String1	-67 ms
Video_Delay/String2	-67 ms
Video_Delay/String3	-00:00:00.067
StreamSize	6212864
StreamSize/String	5.93 MiB (5%)
StreamSize/String1	6 MiB
StreamSize/String2	5.9 MiB
StreamSize/String3	5.93 MiB
StreamSize/String4	5.925 MiB
StreamSize/String5	5.93 MiB (5%)
StreamSize_Proportion	0.04884
Language	en
Language/String	English
Language/String1	English
Language/String2	en
Language/String3	eng
Language/String4	en
ServiceKind	CM
ServiceKind/String	Complete Main
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
ComplexityIndex	12
NumberOfDynamicObjects	11
BedChannelCount/String	1 channel
BedChannelConfiguration	LFE
bsid	16
dialnorm	-31
dialnorm/String	-31 dB
compr	0.53
compr/String	0.53 dB
acmod	7
lfeon	1
dialnorm_Average	-31
dialnorm_Average/String	-31 dB
dialnorm_Minimum	-31
dialnorm_Minimum/String	-31 dB
dialnorm_Maximum	-31
dialnorm_Maximum/String	-31 dB
compr_Average	-2.02
compr_Average/String	-2.02 dB
compr_Minimum	-11.51
compr_Minimum/String	-11.51 dB
compr_Maximum	1.02
compr_Maximum/String	1.02 dB
DTS-HD MA:X

Code: Select all

OriginalSourceMedium_ID	4352
OriginalSourceMedium_ID/String	4352 (0x1100)
Format	DTS
Format/String	DTS XLL X
Format/Info	Digital Theater Systems
Format/Url	https://en.wikipedia.org/wiki/DTS_(sound_system)
Format_Commercial	DTS-HD Master Audio
Format_Commercial_IfAny	DTS-HD Master Audio
Format_Settings_Mode	16
Format_Settings_Endianness	Big
Format_AdditionalFeatures	XLL X
CodecID	A_DTS
Duration	95018.666666
Duration/String	1 min 35 s
Duration/String1	1 min 35 s 19 ms
Duration/String2	1 min 35 s
Duration/String3	00:01:35.019
Duration/String4	00:01:34:72
Duration/String5	00:01:35.019 (00:01:34:72)
BitRate_Mode	VBR
BitRate_Mode/String	Variable
BitRate	4965852
BitRate/String	4 966 kb/s
Channel(s)	8
Channel(s)/String	8 channels
Channel(s)_Original	Object Based
Channel(s)_Original/String	Object Based
ChannelPositions	Object Based
ChannelPositions/String2	Object Based
ChannelLayout	Object Based
SamplesPerFrame	512
SamplingRate	48000
SamplingRate/String	48.0 kHz
FrameRate	93.750
FrameRate/String	93.750 FPS (512 SPF)
BitDepth	24
BitDepth/String	24 bits
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	0
Video_Delay/String3	00:00:00.000
StreamSize	58980676
StreamSize/String	56.2 MiB (14%)
StreamSize/String1	56 MiB
StreamSize/String2	56 MiB
StreamSize/String3	56.2 MiB
StreamSize/String4	56.25 MiB
StreamSize/String5	56.2 MiB (14%)
StreamSize_Proportion	0.13759
Title	Surround 7.1
Language	en
Language/String	English
Language/String1	English
Language/String2	en
Language/String3	eng
Language/String4	en
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
OriginalSourceMedium	Blu-ray
DTS-ES Discrete

Code: Select all

Audio_Format_List	DTS ES XXCH
Audio_Format_WithHint_List	DTS ES XXCH
Audio_Codec_List	DTS ES XXCH
CompleteName	/Users/devster/Movies/Aquaman.2018.IMAX.Edition.1080p.BluRay.DDP7.1.x264-Geek.mkv
FolderName	/Users/devster/Movies
FileNameExtension	Aquaman.2018.IMAX.Edition.1080p.BluRay.DDP7.1.x264-Geek.mkv
FileName	Aquaman.2018.IMAX.Edition.1080p.BluRay.DDP7.1.x264-Geek
FileExtension	mkv
Format	DTS
Format/String	DTS ES XXCH
Format/Info	Digital Theater Systems
Format/Url	https://en.wikipedia.org/wiki/DTS_(sound_system)
Format/Extensions	dts dtshd
Format_Commercial	DTS-ES Discrete
Format_Commercial_IfAny	DTS-ES Discrete
Format_AdditionalFeatures	ES XXCH
FileSize	5233800
FileSize/String	4.99 MiB
FileSize/String1	5 MiB
FileSize/String2	5.0 MiB
FileSize/String3	4.99 MiB
FileSize/String4	4.991 MiB
Duration	27733
Duration/String	27 s 733 ms
Duration/String1	27 s 733 ms
Duration/String2	27 s 733 ms
Duration/String3	00:00:27.733
Duration/String5	00:00:27.733
OverallBitRate_Mode	CBR
OverallBitRate_Mode/String	Constant
OverallBitRate	1509750
OverallBitRate/String	1 510 kb/s
StreamSize	63
StreamSize/String	63.0 Bytes (0%)
StreamSize/String1	63 Bytes
StreamSize/String2	63 Bytes
StreamSize/String3	63.0 Bytes
StreamSize/String4	63.00 Bytes
StreamSize/String5	63.0 Bytes (0%)
StreamSize_Proportion	0.00001
File_Modified_Date	UTC 2019-04-07 22:55:13
File_Modified_Date_Local	2019-04-08 00:55:13
FileExtension_Invalid	dts dtshd
DTS 96/24

Code: Select all

Format	DTS
Format/String	DTS 96/24
Format/Info	Digital Theater Systems
Format/Url	https://en.wikipedia.org/wiki/DTS_(sound_system)
Format_Commercial	DTS 96/24
Format_Commercial_IfAny	DTS 96/24
Format_Settings_Mode	16
Format_Settings_Endianness	Big
Format_AdditionalFeatures	96/24
Duration	295168
Duration/String	4 min 55 s
Duration/String1	4 min 55 s 168 ms
Duration/String2	4 min 55 s
Duration/String3	00:04:55.168
Duration/String5	00:04:55.168
BitRate_Mode	CBR
BitRate_Mode/String	Constant
BitRate	1509750
BitRate/String	1 510 kb/s
Channel(s)	5
Channel(s)/String	5 channels
ChannelPositions	Front: L C R, Side: L R
ChannelPositions/String2	3/2/0.0
ChannelLayout	C L R Ls Rs
SamplesPerFrame	512
SamplingRate	96000
SamplingRate/String	96.0 kHz
FrameRate	187.500
FrameRate/String	187.500 FPS (512 SPF)
BitDepth	24
BitDepth/String	24 bits
Compression_Mode	Lossy
Compression_Mode/String	Lossy
StreamSize	55703736
StreamSize/String	53.1 MiB (100%)
StreamSize/String1	53 MiB
StreamSize/String2	53 MiB
StreamSize/String3	53.1 MiB
StreamSize/String4	53.12 MiB
StreamSize/String5	53.1 MiB (100%)
StreamSize_Proportion	1.00000
TrueHD

Code: Select all

Format	MLP FBA
Format/String	MLP FBA
Format/Info	Meridian Lossless Packing FBA
Format_Commercial	Dolby TrueHD
Format_Commercial_IfAny	Dolby TrueHD
CodecID	A_TRUEHD
CodecID/Url	http://www.dolby.com/consumer/technology/trueHD.html
Duration	16184
Duration/String	16 s 184 ms
Duration/String1	16 s 184 ms
Duration/String2	16 s 184 ms
Duration/String3	00:00:16.184
Duration/String5	00:00:16.184
BitRate_Mode	VBR
BitRate_Mode/String	Variable
BitRate_Maximum	3153000
BitRate_Maximum/String	3 153 kb/s
Channel(s)	6
Channel(s)/String	6 channels
ChannelPositions	Front: L C R, Side: L R, LFE
ChannelPositions/String2	3/2/0.1
ChannelLayout	L R C LFE Ls Rs
SamplesPerFrame	40
SamplingRate	48000
SamplingRate/String	48.0 kHz
FrameRate	1200.000
FrameRate/String	1 200.000 FPS (40 SPF)
Compression_Mode	Lossless
Compression_Mode/String	Lossless
Delay	0
Delay/String3	00:00:00.000
Delay_Source	Container
Delay_Source/String	Container
Video_Delay	0
Video_Delay/String3	00:00:00.000
Default	Yes
Default/String	Yes
Forced	No
Forced/String	No
I only work in black and sometimes very, very dark grey. (Batman)
User avatar
sighunter
Posts: 22
Joined: 26 Aug 2016, 08:08

Re: Multiple audio tracks with different codecs and languages

Post by sighunter »

devster wrote: 15 Apr 2019, 00:14 So, as MediaInfo changed a bit and I realized how I was needlessly trying to replicate the logic already present in MediaBindingBean.java this is a new version of the snippet

Code: Select all

// somewhere at the top 
import net.filebot.Language

      { // map Codec + Format Profile
        def mCFP = [
          "FLAC" : "FLAC",
          "PCM" : "PCM",
          "MP3": "MP3",
          "E-AC-3 JOC": "E-AC-3",
          "DTS ES XXCH": "DTS-ES Discrete",
          "MLP FBA": "TrueHD",
          "MLP FBA 16-ch": "TrueHD"
        ]
        audio.collect { au ->
          def ac1 = any{ au['CodecID/Hint'] }{au['Format/String']}{ au['Format'] } // extends _ac_ which strips spaces > "CodecID/Hint", "Format"
          def ac2 = any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] }
          def atmos = (aco =~ /(?i:atmos)/) ? 'Atmos' : null // _aco_ uses "Codec_Profile", "Format_Profile", "Format_Commercial"
          def combined = allOf{ac1}{ac2}.join(' ')
          def fallback = any{ac1}{ac2}{aco}
          def stream = allOf
            /* _channels_ as it uses "ChannelPositions/String2", "Channel(s)_Original", "Channel(s)"
               compared to _af_ which uses "Channel(s)_Original", "Channel(s)" */
            { allOf{"${channels}"}{au['NumberOfDynamicObjects'] + "obj"}.join('+') }
            { allOf{ mCFP.get(combined, aco) }{atmos}.join('+') } /* bit risky keeping aco as default */
            { Language.findLanguage(au['Language']).ISO3.upperInitial() }
            /* _cf_ not being used > "Codec/Extensions", "Format" */
          return stream
        }.sort{a, b -> a.first() <=> b.first() }*.join(" ").join(", ") }
Unfortunately most of the map is now a bit useless and I only left the ugly MLP FBA.
aco =~ /(?i:atmos)/ is being used as aco.match(/atmos/) fails with Pattern not found: Dolby TrueHD when the string isn't present.
Expected output is:
7.1+15obj TrueHD+Atmos for Dolby Amaze Atmos trailer
5.1 AC-3 for the Amaze regular trailer
5.1 DTS-HD MA Eng, 5.1 PCM Eng, 5.1 AC-3 Eng for Dolby 3D Glass Return Trailer
5.1+11obj E-AC-3+Atmos Eng for Dolby Natures Fury Atmos trailer

I tested it on MacOS, latest version of FileBot available.

Code: Select all

/Applications/FileBot.app//Contents/MacOS/libmediainfo.dylib:
	/usr/local/lib/libmediainfo.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
	/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 489.0.0)
not very informative as version unfortunately.
Feedback welcome.
Hi devster, I want to use your current version but for the life of me can't get it to work. I just pasted it into filebot gui.
I guess I have to add a { at the beginning so the "import net.filebot.Language" is not interpreted as text but that leaves me with:
SyntaxError: missing token: }
but I can't find where to put the }. Tried at the very back but that did not help.
not a programmer, sorry, help pls
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

Code: Select all

{ import net.filebot.Language
        def mCFP = [
          "FLAC" : "FLAC",
          "PCM" : "PCM",
          "MP3": "MP3",
          "E-AC-3 JOC": "E-AC-3",
          "DTS ES XXCH": "DTS-ES Discrete",
          "MLP FBA": "TrueHD",
          "MLP FBA 16-ch": "TrueHD"
        ]
        audio.collect { au ->
          def ac1 = any{ au['CodecID/Hint'] }{au['Format/String']}{ au['Format'] }
          def ac2 = any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] }
          def atmos = (aco =~ /(?i:atmos)/) ? 'Atmos' : null
          def combined = allOf{ac1}{ac2}.join(' ')
          def fallback = any{ac1}{ac2}{aco}
          def stream = allOf
            { allOf{"${channels}"}{au['NumberOfDynamicObjects'] + "obj"}.join('+') }
            { allOf{ mCFP.get(combined, aco) }{atmos}.join('+') }
            { Language.findLanguage(au['Language']).ISO3.upperInitial() }
          return stream
        }.sort{a, b -> a.first() <=> b.first() }*.join(" ").join(", ")
}
sample: 7.1 DTS-HD Master Audio Eng


or you can use my version

Code: Select all

{
	// map codec + format_profile
	def mCFP = [ "MP3" : "MP3",
		"AC 3" : "AC3",
		"E AC 3" : "EAC3",
		"E AC 3 JOC" : "EAC3.Atmos",
		"MLP FBA" : "TrueHD",
		"MLP FBA 16 ch" : "TrueHD.Atmos",
		"DTS" : "DTS",
		"DTS ES XXCH XBR" : "DTS-HD.HRA",
		"DTS ES XBR" : "DTS-HD.HRA",
		"DTS XBR" : "DTS-HD.HRA",
		"DTS XLL" : "DTS-HD.MA",
		"DTS ES XXCH" : "DTS-ES",
		"DTS ES" : "DTS-ES",
		"DTS XLL X" : "DTS.X",
		"DTS 96 24" : "DTS 96-24",
		"AAC LC" : "AAC"]
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') }
	audio.collect { au ->
		def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) }
		def ch = channels
			.tokenize('\\/').take(3)*.toDouble()
			.inject(0, { a, b -> a + b })
			.findAll { it > 0 }.max().toString()
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = { ( au['Format_AdditionalFeatures'] != null) ? audioClean(au['Format_AdditionalFeatures']) : '' }
		def combined = allOf{codec}{format_profile}.join(' ')
		def stream = allOf
                   { mCFP.get(combined, 'UNKNOWN_FORMAT--'+combined+'--') }
                   { ch }
                   { au.'LanguageString3'.upperInitial() }
		println "MISSING_mCFP_FORMAT: "+combined
		return stream
	}*.join(".").unique().join(".&.")
}
sample: DTS-HD.MA.7.1.Eng
User avatar
sighunter
Posts: 22
Joined: 26 Aug 2016, 08:08

Re: Multiple audio tracks with different codecs and languages

Post by sighunter »

kim wrote: 29 Apr 2019, 16:10

Code: Select all

{ import net.filebot.Language
        def mCFP = [
          "FLAC" : "FLAC",
          "PCM" : "PCM",
          "MP3": "MP3",
          "E-AC-3 JOC": "E-AC-3",
          "DTS ES XXCH": "DTS-ES Discrete",
          "MLP FBA": "TrueHD",
          "MLP FBA 16-ch": "TrueHD"
        ]
        audio.collect { au ->
          def ac1 = any{ au['CodecID/Hint'] }{au['Format/String']}{ au['Format'] }
          def ac2 = any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] }
          def atmos = (aco =~ /(?i:atmos)/) ? 'Atmos' : null
          def combined = allOf{ac1}{ac2}.join(' ')
          def fallback = any{ac1}{ac2}{aco}
          def stream = allOf
            { allOf{"${channels}"}{au['NumberOfDynamicObjects'] + "obj"}.join('+') }
            { allOf{ mCFP.get(combined, aco) }{atmos}.join('+') }
            { Language.findLanguage(au['Language']).ISO3.upperInitial() }
          return stream
        }.sort{a, b -> a.first() <=> b.first() }*.join(" ").join(", ")
}
sample: 7.1 DTS-HD Master Audio Eng


or you can use my version

Code: Select all

{
	// map codec + format_profile
	def mCFP = [ "MP3" : "MP3",
		"AC 3" : "AC3",
		"E AC 3" : "EAC3",
		"E AC 3 JOC" : "EAC3.Atmos",
		"MLP FBA" : "TrueHD",
		"MLP FBA 16 ch" : "TrueHD.Atmos",
		"DTS" : "DTS",
		"DTS ES XXCH XBR" : "DTS-HD.HRA",
		"DTS ES XBR" : "DTS-HD.HRA",
		"DTS XBR" : "DTS-HD.HRA",
		"DTS XLL" : "DTS-HD.MA",
		"DTS ES XXCH" : "DTS-ES",
		"DTS ES" : "DTS-ES",
		"DTS XLL X" : "DTS.X",
		"DTS 96 24" : "DTS 96-24",
		"AAC LC" : "AAC"]
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') }
	audio.collect { au ->
		def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) }
		def ch = channels
			.tokenize('\\/').take(3)*.toDouble()
			.inject(0, { a, b -> a + b })
			.findAll { it > 0 }.max().toString()
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = { ( au['Format_AdditionalFeatures'] != null) ? audioClean(au['Format_AdditionalFeatures']) : '' }
		def combined = allOf{codec}{format_profile}.join(' ')
		def stream = allOf
                   { mCFP.get(combined, 'UNKNOWN_FORMAT--'+combined+'--') }
                   { ch }
                   { au.'LanguageString3'.upperInitial() }
		println "MISSING_mCFP_FORMAT: "+combined
		return stream
	}*.join(".").unique().join(".&.")
}
sample: DTS-HD.MA.7.1.Eng
thank you very much kim, I chose and adapted your version

FYI, I added
"PCM" : "PCM",
"DTS ES XLL" : "DTS-HD MA",
"DTS ES XXCH XLL" : "DTS-HD MA",
"AC 3 Dep" : "E-AC3",
"AAC LC SBR" : "AAC",
which displayed UNKNOWN_FORMAT for some of my movies
Last edited by sighunter on 30 Apr 2019, 14:42, edited 1 time in total.
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

I think this is wrong
"DTS ES XXCH XLL" : "DTS-ES",
6.1 ch ?
because XLL is better then ES

should be
"DTS ES XXCH XLL" : "DTS-HD MA",
https://wiki.videolan.org/DTS/

you got more info on "AC 3 Dep" ?
User avatar
sighunter
Posts: 22
Joined: 26 Aug 2016, 08:08

Re: Multiple audio tracks with different codecs and languages

Post by sighunter »

kim wrote: 30 Apr 2019, 14:21 I think this is wrong
"DTS ES XXCH XLL" : "DTS-ES",
6.1 ch ?
because XLL is better then ES

should be
"DTS ES XXCH XLL" : "DTS-HD MA",
https://wiki.videolan.org/DTS/

you got more info on "AC 3 Dep" ?
you are correct of course, XLL stands for lossless, which should therefore be DTS-HD MA

"AC 3 Dep" was the german audio track from "finding dory" bluray. here is the mediainfo

Code: Select all

Audio #1
Count                                    : 305
Count of stream of this kind             : 2
Kind of stream                           : Audio
Kind of stream                           : Audio
Stream identifier                        : 0
Stream identifier                        : 1
StreamOrder                              : 1
ID                                       : 2
ID                                       : 2
Unique ID                                : 9548324243094778268
Format                                   : AC-3
Format                                   : E-AC-3
Format/Info                              : Enhanced AC-3
Format/Url                               : https://en.wikipedia.org/wiki/AC3
Commercial name                          : Dolby Digital Plus
Commercial name                          : Dolby Digital Plus
Format profile                           : Blu-ray Disc
Format settings, Endianness              : Big
Format_AdditionalFeatures                : Dep
Internet media type                      : audio/eac3
Codec ID                                 : A_EAC3
Duration                                 : 5823648.000000
Duration                                 : 1 h 37 min
Duration                                 : 1 h 37 min 3s 648 ms
Duration                                 : 1 h 37 min
Duration                                 : 01:37:03.648
Duration                                 : 01:37:50:19
Duration                                 : 01:37:03.648 (01:37:50:19)
Bit rate mode                            : CBR
Bit rate mode                            : konstant
Bit rate                                 : 896000
Bit rate                                 : 896 kb/s
Channel(s)                               : 6
Channel(s)                               : 6 Kanäle
Channel(s)_Original                      : 8
Channel(s)_Original                      : 8 Kanäle
Channel positions                        : Front: L C R, Side: L R, Back: L R, LFE
Channel positions                        : 3/2/0.1
Channel layout                           : L R C LFE Ls Rs Lb Rb
Samples per frame                        : 1536
Sampling rate                            : 48000
Sampling rate                            : 48,0 kHz
Samples count                            : 279535104
Frame rate                               : 31.250
Frame rate                               : 31,250 FPS (1536 SPF)
Frame count                              : 181989
Compression mode                         : Lossy
Delay                                    : 0
Delay                                    : 00:00:00.000
Delay, origin                            : Container
Delay relative to video                  : 0
Delay relative to video                  : 00:00:00.000
Stream size                              : 652248576
Stream size                              : 622 MiB (3%)
Stream size                              : 622 MiB
Stream size                              : 622 MiB
Stream size                              : 622 MiB
Stream size                              : 622,0 MiB
Stream size                              : 622 MiB (3%)
Proportion of this stream                : 0.03370
Title                                    : ger
Language                                 : de
Language                                 : Deutsch
Language                                 : Deutsch
Language                                 : de
Language                                 : deu
Language                                 : de
Service kind                             : CM
Service kind                             : Complete Main
Default                                  : Yes
Default                                  : Ja
Forced                                   : No
Forced                                   : Nein
bsid                                     : 16
dialnorm                                 : -31
dialnorm                                 : -31 dB
compr                                    : -4.53
compr                                    : -4.53 dB
acmod                                    : 7 / 5
lfeon                                    : 1 / 0
dialnorm_Average                         : -31
dialnorm_Average                         : -31 dB
dialnorm_Minimum                         : -31
dialnorm_Minimum                         : -31 dB
dialnorm_Maximum                         : -31
dialnorm_Maximum                         : -31 dB
dialnorm_Count                           : 654
compr_Average                            : 2.01
compr_Average                            : 2.01 dB
compr_Minimum                            : -4.53
compr_Minimum                            : -4.53 dB
compr_Maximum                            : 4.22
compr_Maximum                            : 4.22 dB
compr_Count                              : 252
dynrng_Average                           : 0.63
dynrng_Average                           : 0.63 dB
dynrng_Minimum                           : -3.87
dynrng_Minimum                           : -3.87 dB
dynrng_Maximum                           : 4.54
dynrng_Maximum                           : 4.54 dB
dynrng_Count                             : 653
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

kim wrote: 30 Apr 2019, 14:21 you got more info on "AC 3 Dep" ?
https://github.com/MediaArea/MediaInfoL ... l.cpp#L436
seems to be an additional format feature of E-AC-3
I only work in black and sometimes very, very dark grey. (Batman)
stephen147
Donor
Posts: 131
Joined: 01 Sep 2015, 22:40

Re: Multiple audio tracks with different codecs and languages

Post by stephen147 »

I've done my tweak on it using all the codes here as I'm not as good as you lot with coding the base code.

Thanks to all concerned.

:!: This only gets the 1st audio channel.

Code: Select all

{
	def mCFP =
	[
	'AAC LC SBR' : 'AAC',
	'AAC LC' : 'AAC',
	'AC 3 Dep' : 'E-AC3',
	'AC 3' : 'AC3',
	'DTS 96 24' : 'DTS 96-24',
	'DTS ES XBR' : 'DTS-HD HRA',
	'DTS ES XLL' : 'DTS-HD MA',
	'DTS ES XXCH XBR' : 'DTS-HD HRA',
	'DTS ES XXCH XLL' : 'DTS-HD MA',
	'DTS ES XXCH' : 'DTS-ES',
	'DTS ES' : 'DTS-ES',
	'DTS XBR' : 'DTS-HD HRA',
	'DTS XLL X' : 'DTS X',
	'DTS XLL' : 'DTS-HD MA',
	'DTS' : 'DTS',
	'E AC 3 JOC' : 'EAC3 Atmos',
	'E AC 3' : 'EAC3',
	'MLP FBA 16 ch' : 'TrueHD Atmos',
	'MLP FBA' : 'TrueHD',
	'MP3' : 'MP3',
	'PCM' : 'PCM'
	]
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') }
	audio.collect { au ->
		def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) }
		def dynChannel = {au['NumberOfDynamicObjects'] + 'Objs\''};
		def ch = channels
		.tokenize('\\/').take(3)*.toDouble()
		.inject(0, { a, b -> a + b })
		.findAll { it > 0 }.max().toString() + 'ch'
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = { ( au['Format_AdditionalFeatures'] != null) ? audioClean(au['Format_AdditionalFeatures']) : '' }
		def combined = allOf{codec}{format_profile}.join(' ')
		def stream = allOf
		{ mCFP.get(combined, 'UNKNOWN_FORMAT--'+combined+'--') }
		{ dynChannel }
		{ ch }
		//{ au.'LanguageString3'.upperInitial() }
		println "MISSING_mCFP_FORMAT: "+combined
		return stream
		}[0].join( ' ' )
	}
:!: Output from the few files in my collection that contain these audio formats + some others that don't.
Image
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

This took me some time to make, I hope you like it:

All 1 one format, use:

Code: Select all

allStreams.join(' & ').space('.')
or

Code: Select all

bestStream.space('.')
Remember to add or edit the order of "codecList" if you prefer one codec over another
(first to last order)

Code: Select all

{
	def codecList =
	[
	'MP3' : 'MP3',
	'PCM' : 'PCM',
	'AAC LC' : 'AAC',
	'AAC LC SBR' : 'AAC',
	'AC 3' : 'AC3',
	'AC 3 Dep' : 'EAC3',
	'E AC 3' : 'EAC3',
	'E AC 3 JOC' : 'EAC3 Atmos',
	'DTS' : 'DTS',
	'DTS 96 24' : 'DTS 96-24',
	'DTS ES' : 'DTS-ES',
	'DTS ES XXCH' : 'DTS-ES',
	'DTS XBR' : 'DTS-HD HRA',
	'DTS ES XBR' : 'DTS-HD HRA',
	'DTS ES XXCH XBR' : 'DTS-HD HRA',
	'DTS XLL' : 'DTS-HD MA',
	'DTS ES XLL' : 'DTS-HD MA',
	'DTS ES XXCH XLL' : 'DTS-HD MA',
	'DTS XLL X' : 'DTS X',
	'MLP FBA' : 'TrueHD',
	'MLP FBA 16 ch' : 'TrueHD Atmos'
	]	
	def audioStreams = []
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') }
	def combined

	audio.collect{ au ->
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = { ( au['Format_AdditionalFeatures'] != null) ? audioClean(au['Format_AdditionalFeatures']) : '' }
		combined = allOf{codec}{format_profile}.join(' ')
		def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) }
		def ch = channels
		.tokenize('\\/').take(3)*.toDouble()
		.inject(0, { a, b -> a + b })
		.findAll { it > 0 }.max().toString()

		audioStreams << ['index' : codecList.findIndexOf {it.key == combined}, 'codec' : codecList.get(combined, 'UNKNOWN_FORMAT'), 'combined' : combined, 'ch' : ch, 'objects' : any{'(' + au['NumberOfDynamicObjects'] + ' Objs)'}{' '}, 'lang' : any{au.'LanguageString3'.upperInitial()}{' '} ]
		return audioStreams
	}

	def allStreams = audioStreams.collect{ it.codec + ' ' + it.ch + ' ' + it.objects + ' ' + it.lang }.unique()
	def bestStream = audioStreams.unique().findAll{ it.index == audioStreams.index.max() }.collect{ it.codec + ' ' + it.ch + ' ' + it.objects + ' ' + it.lang }.find{ it }

	allStreams.join(' & ').space('.')
	bestStream.space('.')
}
stephen147
Donor
Posts: 131
Joined: 01 Sep 2015, 22:40

Re: Multiple audio tracks with different codecs and languages

Post by stephen147 »

kim wrote: 04 May 2019, 03:27 This took me some time to make, I hope you like it:
Cool, thanks for the example. I'll stick with grabbing the [0] stream as this will be the primary one. ;)
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

Well you can just use

Code: Select all

allStreams.first()
Version 2
added

Code: Select all

[allStreams.first(), bestStream].unique().join(' & ').space('.')
e.g.
DTS-HD.MA.7.1.Eng.&.TrueHD.Atmos.7.1.(11.Objs).Eng
if you don't want some of the output just edit

Code: Select all

def filter = { it.codec + ' ' + it.ch + ' ' + it.objects + ' ' + it.lang }
you can also use this to list the first 3

Code: Select all

allStreams.take(3).join(' & ').space('.')

Code: Select all

{
	def codecList =
	[
	'MP3' : 'MP3',
	'PCM' : 'PCM',
	'AAC LC' : 'AAC',
	'AAC LC SBR' : 'AAC',
	'AC 3' : 'AC3',
	'AC 3 Dep' : 'EAC3',
	'E AC 3' : 'EAC3',
	'E AC 3 JOC' : 'EAC3 Atmos',
	'DTS' : 'DTS',
	'DTS 96 24' : 'DTS 96-24',
	'DTS ES' : 'DTS-ES',
	'DTS ES XXCH' : 'DTS-ES',
	'DTS XBR' : 'DTS-HD HRA',
	'DTS ES XBR' : 'DTS-HD HRA',
	'DTS ES XXCH XBR' : 'DTS-HD HRA',
	'DTS XLL' : 'DTS-HD MA',
	'DTS ES XLL' : 'DTS-HD MA',
	'DTS ES XXCH XLL' : 'DTS-HD MA',
	'DTS XLL X' : 'DTS X',
	'MLP FBA' : 'TrueHD',
	'MLP FBA 16 ch' : 'TrueHD Atmos'
	]	
	def audioStreams = []
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') }
	def filter = { it.codec + ' ' + it.ch + ' ' + it.objects + ' ' + it.lang }
	def combined

	audio.collect{ au ->
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = any{ audioClean(au['Format_AdditionalFeatures'])}{}
		def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) }
		def ch = channels.tokenize('\\/').take(3)*.toDouble().inject(0, { a, b -> a + b }).findAll { it > 0 }.max().toString()

		combined = allOf{codec}{format_profile}.join(' ')
		audioStreams << ['index' : codecList.findIndexOf {it.key == combined}, 'codec' : codecList.get(combined, 'UNKNOWN_FORMAT'), 'combined' : combined, 'ch' : ch, 'objects' : any{'(' + au['NumberOfDynamicObjects'] + ' Objs)'}{' '}, 'lang' : any{au.'LanguageString3'.upperInitial()}{' '} ]
		return audioStreams
	}

	def allStreams = audioStreams.collect{ filter(it) }.unique()
	def bestStream = audioStreams.unique().findAll{ it.index == audioStreams.index.max() }.collect{ filter(it) }.find{ it }

	allStreams.join(' & ').space('.')
	bestStream.space('.')
	[allStreams.first(), bestStream].unique().join(' & ').space('.')
}
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

Version 3
added check for defaultStream

Code: Select all

{
	def codecList =
	[
	'MP3' : 'MP3',
	'PCM' : 'PCM',
	'AAC LC' : 'AAC',
	'AAC LC SBR' : 'AAC',
	'AC 3' : 'AC3',
	'AC 3 Dep' : 'EAC3',
	'E AC 3' : 'EAC3',
	'E AC 3 JOC' : 'EAC3 Atmos',
	'DTS' : 'DTS',
	'DTS 96 24' : 'DTS 96-24',
	'DTS ES' : 'DTS-ES',
	'DTS ES XXCH' : 'DTS-ES',
	'DTS XBR' : 'DTS-HD HRA',
	'DTS ES XBR' : 'DTS-HD HRA',
	'DTS ES XXCH XBR' : 'DTS-HD HRA',
	'DTS XLL' : 'DTS-HD MA',
	'DTS ES XLL' : 'DTS-HD MA',
	'DTS ES XXCH XLL' : 'DTS-HD MA',
	'DTS XLL X' : 'DTS X',
	'MLP FBA' : 'TrueHD',
	'MLP FBA 16 ch' : 'TrueHD Atmos'
	]	
	def audioStreams = []
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6/,'5.1').replaceAll(/8/,'7.1') }
	def filter = { it.codec + ' ' + it.ch + ' ' + it.objects + ' ' + it.lang }	

	audio.collect{ au ->
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = any{ audioClean(au['Format_AdditionalFeatures'])}{}
		def channels = any{ channelClean(au['ChannelPositionsString2'])}{ channelClean(au['ChannelsOriginal'])}{ channelClean(au['Channels']) }
		def ch = channels.tokenize('\\/').take(3)*.toDouble().inject(0, { a, b -> a + b }).findAll { it > 0 }.max().toString()

		def combined = allOf{codec}{format_profile}.join(' ')
		audioStreams << ['index' : codecList.findIndexOf {it.key == combined}, 'default' : au['default'][0].toBoolean(), 'codec' : codecList.get(combined, 'UNKNOWN_FORMAT'), 'combined' : combined, 'ch' : ch, 'objects' : any{'(' + au['NumberOfDynamicObjects'] + ' Objs)'}{' '}, 'lang' : any{au.'LanguageString3'.upperInitial()}{' '} ]
		return audioStreams
	}

	def allStreams = audioStreams.collect{ filter(it) }.unique()
	def bestStream = audioStreams.unique().findAll{ it.index == audioStreams.index.max() }.collect{ filter(it) }.find{ it }
	def defaultStream = audioStreams.findAll{it.default == true}.collect{ filter(it) }.find{ it }
	
	allStreams.join(' & ').space('.')
	bestStream.space('.')
	[defaultStream, bestStream].unique().join(' & ').space('.')
}
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

You may try this for all audio streams:

Code: Select all

      { import java.math.RoundingMode
        // audio map, fill in with your preferred one
        def mCFP = []

        audio.collect { au ->
          /* Format seems to be consistently defined and identical to Format/String
             Format_Profile and Format_AdditionalFeatures instead
             seem to be usually mutually exclusive
             Format_Commercial (and _If_Any variant) seem to be defined
             mainly for Dolby/DTS formats */
          def _ac = any
                      { allOf
                        { au["Format"] }
                        { au["Format_Profile"] }
                        { au["Format_AdditionalFeatures"] }
                        .join(" ") }
                      { au["Format_Commercial"] }

          /* original _aco_ binding uses "Codec_Profile", "Format_Profile", "Format_Commercial" */
          def _aco = any{ au["Codec_Profile"] }{ au["Format_Profile"] }{ au["Format_Commercial"] }

          /* def atmos = (_aco =~ /(?i:atmos)/) ? "Atmos" : null */
          def isAtmos = {
            def _fAtmos = any{audio.FormatCommercial =~ /(?i)atmos/}{false}
            def _oAtmos = any{audio.NumberOfDynamicObjects}{false}
            if (_fAtmos || _oAtmos) { return "Atmos" }
          }

          /* _channels_ uses "ChannelPositions/String2", "Channel(s)_Original", "Channel(s)"
             compared to _af_ which uses "Channel(s)_Original", "Channel(s)"
             using another variable allows calculating the output for each audio stream */
          String    _channels = any
                                  { au["ChannelPositions/String2"] }
                                  { au["Channel(s)_Original"] }
                                  { au["Channel(s)"] }
          String    _ch

          /* _channels can contain no numbers */
          Object    splitCh = _channels =~ /^(?i)object.based$/ ? "Object Based" :
                              _channels.tokenize("\\/\\.")
                              /* the below may be needed for 3/2/0.2.1/3/2/0.1 files, of
                                  which I have no examples anymore since MediaInfo 18.12 */
                              // _channels.tokenize("\\/").take(3)*.tokenize("\\.")
                              //          .flatten()*.toInteger()
          switch (splitCh) {
            case { it instanceof String }:
              /* Object Based channels, which usually have also a numeric value */
              def _chDeep = any{ au["Channel(s)"] }{ au["Channel(s)/String"].replaceAll("channels", "") }
              _ch = allOf{ splitCh }{ _chDeep + "ch" }.join(" ")
              break

            case { it.size > 4 }:
              /* format similar to 3/2/0.2.1, coercing the last value to Double fails */
              def wide = splitCh.takeRight(1)
              Double main = splitCh.take(4)*.toDouble().inject(0, { a, b -> a + b })
              Double sub = Double.parseDouble("0." + wide.last())
              _ch = (main + sub).toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
              break

            case { it.size > 1 }:
              /* original logic is _mostly_ unchanged if format is like 3/2/0.1 */
              Double sub = Double.parseDouble(splitCh.takeRight(2).join("."))
              _ch = splitCh.take(2)*.toDouble().plus(sub).inject(0, { a, b -> a + b })
                           .toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
              break

            default:
              _ch = splitCh.first().toDouble()
          }
I only work in black and sometimes very, very dark grey. (Batman)
kim
Power User
Posts: 1251
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim »

Version 4
changed: bestStream to preferredStream
added: bestBitRate
added: support for chFilter (change 'ch' : ch, to "'ch' : chFilter,")

Code: Select all

{
	def codecList =
	[
	'MP3' : 'MP3',
	'PCM' : 'PCM',
	'AAC LC' : 'AAC',
	'AAC LC SBR' : 'AAC',
	'AC 3' : 'AC3',
	'AC 3 Dep' : 'EAC3',
	'E AC 3' : 'EAC3',
	'E AC 3 JOC' : 'EAC3 Atmos',
	'DTS' : 'DTS',
	'DTS 96 24' : 'DTS 96-24',
	'DTS ES' : 'DTS-ES',
	'DTS ES XXCH' : 'DTS-ES',
	'DTS XBR' : 'DTS-HD HRA',
	'DTS ES XBR' : 'DTS-HD HRA',
	'DTS ES XXCH XBR' : 'DTS-HD HRA',
	'DTS XLL' : 'DTS-HD MA',
	'DTS ES XLL' : 'DTS-HD MA',
	'DTS ES XXCH XLL' : 'DTS-HD MA',
	'DTS XLL X' : 'DTS X',
	'MLP FBA' : 'TrueHD',
	'MLP FBA 16 ch' : 'TrueHD Atmos'
	]
	def filter = { [it.codec, it.ch, it.objects, it.lang] }

	def audioStreams = []
	def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ').slash(' ') }
	def channelClean = { it.replaceAll(/Debug.+|Object\sBased\s?\/?|(\d+)?\sobjects\s\/\s|0.(?=\d.\d)|20/).replaceAll(/6.0/,'5.1').replaceAll(/8.0/,'7.1')}
	def oneStream = { it.collect{ filter(it) }*.minus(null).unique().flatten().join(' ') }
	def dString = { it.toDouble().toString() }
	def toInt = { it.toInteger() }

	audio.collect{ au ->
		def codec = audioClean(any{ au['CodecID/Hint'] }{ au['Format'] })
		def format_profile = any{ audioClean(au['Format_AdditionalFeatures'])}{}
		def String ch = any{ channelClean(au.ChannelPositionsString2).tokenize('\\/')*.toDouble().toString().sum() }
			{ channelClean(dString(au.ChannelsOriginal)) } { channelClean(dString(au.Channels)) }

		def chFilter =	(( ( (ac == 'AAC'||ac == 'MP3') && ch != '2.0') || ( (ac == 'AC3'||ac == 'EAC3'||ac == 'DTS'||ac == 'TrueHD'||ac == 'MLPFBA') && ch != '5.1' ) ) ? ch : null)

		def combined = allOf{codec}{format_profile}.join(' ')
		audioStreams << ['index' : codecList.findIndexOf {it.key == combined}, 'default' : au['default'][0].toBoolean(),
		'codec' : codecList.get(combined, 'UNKNOWN_FORMAT'), 'combined' : combined, 'ch' : ch, 
		'bitrate' : any{toInt(au.BitRate)}{toInt(au.BitRate_Maximum)}{au.FrameRate.toDouble()}{null},
		'objects' : any{'[' + au['NumberOfDynamicObjects'] + ' Objs]'}{null}, 'lang' : any{au.'LanguageString3'.upperInitial()}{null} ]
		return audioStreams
	}

	def allStreams = audioStreams.collect{ filter(it) }*.minus(null).unique()*.join(' ')
	def preferredStream = oneStream(audioStreams.findAll{ it.index == audioStreams.index.max() })
	def bestBitRate = oneStream(audioStreams.findAll{ it.bitrate == audioStreams.bitrate.max() })
	def defaultStream = oneStream(audioStreams.findAll{it.default == true})

	allStreams.join(' & ').space('.')
	preferredStream.space('.')
	defaultStream.space('.')
	bestBitRate.space('.')
	[bestBitRate, preferredStream].unique().join(' & ').space('.')
	[defaultStream, bestBitRate].unique().join(' & ').space('.')	
}
User avatar
rednoah
The Source
Posts: 23469
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Multiple audio tracks with different codecs and languages

Post by rednoah »

I've got new builds for testing here:
https://get.filebot.net/filebot/BETA/

The new builds come with MediaInfo 19.04 which hopefully makes things work better again.
:idea: Please read the FAQ and How to Request Help.
devster
Posts: 417
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster »

Found a new weird audio.
With MediaInfo 18.12 and 19.04 the result is the following:

Code: Select all

Audio
Count                            : 298
StreamCount                      : 1
StreamKind                       : Audio
StreamKind/String                : Audio
StreamKindID                     : 0
StreamOrder                      : 1
ID                               : 2
ID/String                        : 2
UniqueID                         : 8654701659007087417
Format                           : AC-3
Format/String                    : E-AC-3
Format/Info                      : Enhanced AC-3
Format/Url                       : https://en.wikipedia.org/wiki/AC3
Format_Commercial                : Dolby Digital Plus
Format_Commercial_IfAny          : Dolby Digital Plus
Format_Profile                   : Blu-ray Disc
Format_Settings_Endianness       : Big
Format_AdditionalFeatures        : Dep
InternetMediaType                : audio/eac3
CodecID                          : A_EAC3
Duration                         : 8089088.000000
Duration/String                  : 2h 14mn
Duration/String1                 : 2h 14mn 49s 88ms
Duration/String2                 : 2h 14mn
Duration/String3                 : 02:14:49.088
Duration/String4                 : 02:15:54:10
Duration/String5                 : 02:14:49.088 (02:15:54:10)
BitRate_Mode                     : CBR
BitRate_Mode/String              : CBR
BitRate                          : 1280000
BitRate/String                   : 1280 Kbps
Channel(s)                       : 8
Channel(s)/String                : 8 channel3
ChannelPositions                 : Front: L C R, Side: L R, Back: L R, LFE
ChannelPositions/String2         : 3/2/0.1
ChannelLayout                    : L R C LFE Ls Rs Lb Rb
SamplesPerFrame                  : 1536
SamplingRate                     : 48000
SamplingRate/String              : 48.0 KHz
SamplingCount                    : 388276224
FrameRate                        : 31.250
FrameRate/String                 : 31.250 fps3 (1536 SPF)
FrameCount                       : 252784
Compression_Mode                 : Lossy
Compression_Mode/String          : Lossy
Delay                            : 0
Delay/String3                    : 00:00:00.000
Delay_Source                     : Container
Delay_Source/String              : Container
Video_Delay                      : 0
Video_Delay/String3              : 00:00:00.000
StreamSize                       : 1294254080
StreamSize/String                : 1.21 GiB (6%)
StreamSize/String1               : 1 GiB
StreamSize/String2               : 1.2 GiB
StreamSize/String3               : 1.21 GiB
StreamSize/String4               : 1.205 GiB
StreamSize/String5               : 1.21 GiB (6%)
StreamSize_Proportion            : 0.06499
Title                            : Dolby Digital Plus Audio / 7.1 / 48 kHz / 1280 kbps
Language                         : en
Language/String                  : en
Language/String1                 : en
Language/String2                 : en
Language/String3                 : eng
Language/String4                 : en
ServiceKind                      : CM
ServiceKind/String               : Complete Main
Default                          : Yes
Default/String                   : Yes
Forced                           : No
Forced/String                    : No
bsid                             : 16
dialnorm                         : -31
dialnorm                         : -31 dB
compr                            : -0.28
compr                            : -0.28 dB
acmod                            : 7 / 5
lfeon                            : 1 / 0
dialnorm_Average                 : -31
dialnorm_Average                 : -31 dB
dialnorm_Minimum                 : -31
dialnorm_Minimum                 : -31 dB
dialnorm_Maximum                 : -31
dialnorm_Maximum                 : -31 dB
dialnorm_Count                   : 3476
compr_Average                    : -2.76
compr_Average                    : -2.76 dB
compr_Minimum                    : -6.88
compr_Minimum                    : -6.88 dB
compr_Maximum                    : -0.56
compr_Maximum                    : -0.56 dB
compr_Count                      : 700
Now, a few points:
  • Format/String and Format differ (AC-3 vs E-AC-3) for this I modified my last script by changing the Format into any{au["Format/String"] }{ au["Format"] }
  • never seen Format_Profile: Blu-ray Disc or Format_AdditionalFeatures: Dep, any info on them?
  • channels seem 8, which is consistent with ChannelPositions and ChannelLayout but not with ChannelPositions/String2 which reports 5.1, do I really need to parse raw ChannelPositions to fix this? any smarter ideas?
I'm a bit speechless.
I only work in black and sometimes very, very dark grey. (Batman)
Post Reply