Multiple audio tracks with different codecs and languages

All about user-defined episode / movie format expressions
Post Reply
User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Multiple audio tracks with different codecs and languages

Post by devster » 21 Aug 2017, 23:29

I have a file with multiple audio tracks each with a different codec and language, usually also different channels.
Usually the {channels} and {ac} bindings are enough and for most movies something like:

Code: Select all

{ allOf
  {[channels,ac].join(" ")}
  { def a = audioLanguages
    a.size() > 1 ? a.ISO3.join(", ").upperInitial() : a.ISO3.first() }
  .join(" ") }
is acceptable.
I'm however trying to find a way to access each track separately. The ideal output would be:

Code: Select all

7.1 DTS Eng, 2.0 AC3 Ita
kim already did something which is quite close here @viewtopic.php?f=5&t=2&p=29923#p29923 but it uses another method which does not separate each audio stream.
I only work in black and sometimes very, very dark grey. (Batman)

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 21 Aug 2017, 23:54

I just found @viewtopic.php?f=8&t=1038, which goes even closer, but the following is only partial and definitely not elegant:

Code: Select all

{ import net.filebot.Language;
  audio.collect { [it['ChannelPositions/String2'], it['Codec'],
    Language.findLanguage(it['Language']).ISO3.upperInitial()] }*.join(' ').join(' + ') }
especially the first part relative to the channels, which I cannot replicate from MediaBindingBean.java#L384 which I presume is the origin of the {channels} binding.
I only work in black and sometimes very, very dark grey. (Batman)

kim
Power User
Posts: 608
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim » 22 Aug 2017, 01:08

it took me a long time to get the last part down to e.g 7.1 so someone else most do that:

here is a semi working format (without the import stuff):

Code: Select all

{
audio.collect { [it['ChannelPositionsString2'], it['Language/String3'].upperInitial(), it['Codec'], ] }*.join(' ').join(' + ');
}

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 22 Aug 2017, 09:20

Untested, but I went and looked for what filebot actually does to define the bindings and this is as close as I can get, definitely not pretty though

Code: Select all

{ import java.math.RoundingMode
  import net.filebot.Language
  audio.collect {
    def au = it
    def channels = any{ au['ChannelPositions/String2'] }{ au['Channel(s)_Original'] }{ au['Channel(s)'] } 
    def ch = channels.tokenize('\\/')*.toDouble().inject(0, { a, b -> a + b }).findAll { it > 0 }
                     .max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
    def codec = any{ au['CodecID/Hint'] }{ au['Format'] }.replaceAll(/['`´‘’ʻ\p{Punct}\p{Space}]/, '')
    return [ch, codec, Language.findLanguage(au['Language']).ISO3.upperInitial()]
  }*.join(" ").join(", ") }
EDIT: this should work, still ugly
I only work in black and sometimes very, very dark grey. (Batman)

kim
Power User
Posts: 608
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim » 22 Aug 2017, 17:20

You are adding them together:
ChannelPositions/String2 3/2/2.1 / 3/2/0.1 = 12.2 DTS Eng
= BAD

also:
Expression yields empty value: For input string: "Object Based"
Binding "Language": undefined
with AAC file

Code: Select all

Expression yields empty value: multiple points
with DTS-HD.HRA file

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 22 Aug 2017, 17:43

Uhm, that's strange, I just renamed 2 animes and a movie and it seems to be working for me using that snippet, but I don't have any files with stuff more complicated than 7.1 DTS.
I slimmed it a little and I'm using more allOf which might fix the undefined bindings at least:

Code: Select all

{ import java.math.RoundingMode
  import net.filebot.Language
  audio.collect { au ->
    def channels = any{ au['ChannelPositions/String2'] }{ au['Channel(s)_Original'] }{ au['Channel(s)'] }
    def ch = channels.tokenize('\\/')*.toDouble()
                  .inject(0, { a, b -> a + b }).findAll { it > 0 }
                  .max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
   def codec = any{ au['CodecID/Hint'] }{ au['Format'] }.replaceAll(/['`´‘’ʻ\p{Punct}\p{Space}]/, '')
   return allOf{ch}{codec}{Language.findLanguage(au['Language']).ISO3.upperInitial()} }*.join(" ").join(", ") }
I just tried to do what filebot does internally to create the {channels}, {ac} and {lang} bindings.
Last edited by devster on 22 Aug 2017, 18:49, edited 1 time in total.
I only work in black and sometimes very, very dark grey. (Batman)

kim
Power User
Posts: 608
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim » 22 Aug 2017, 18:07

now you only need to fix the adding part
12.2 DTS Eng, 12.2 DTS Eng, 12.2 DTS Eng, 18.3 DTS Eng, 18.3 DTS Eng, 18.3 DTS Eng, 12.2 DTS Eng, 12.2 DTS Eng, 12.2 DTS Eng
12.2 DTS Eng, 7.1 TrueHD Eng, 5.1 AC3 Eng, 5.1 DTS Eng, 5.1 DTS Eng, 5.1 AC3 Eng, 5.1 AC3 Fra, 5.1 AC3 Ita, 5.1 AC3 Spa, 5.1 AC3 Nld, 5.1 AC3 Cat, 5.1 AC3 Spa, 5.1 AC3 Nld

Code: Select all

{ import java.math.RoundingMode
  import net.filebot.Language
  audio.collect { au ->
    def channels = any{ au['ChannelPositions/String2'].replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '') }{ au['Channel(s)_Original'] }{ au['Channel(s)'] }
    def ch = channels.tokenize('\\/')*.toDouble()
                  .inject(0, { a, b -> a + b }).findAll { it > 0 }
                  .max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
   def codec = any{ au['CodecID/Hint'] }{ au['Format'] }.replaceAll(/['`´‘’ʻ\p{Punct}\p{Space}]/, '')
   return allOf{ch}{codec}{Language.findLanguage(au['Language']).ISO3.upperInitial()} }*.join(" ").join(", ") }

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 23 Aug 2017, 20:33

Thanks. I'll trust you on the actual results as I don't have any files to test it on. Do you happen to know if there are around some test files for Object Based audio streams, like the ones on the Dolby websites?
Also, why do you also match for

Code: Select all

0.(?=\d.\d)
Which kind of edge case does this resolve?
I only work in black and sometimes very, very dark grey. (Batman)

kim
Power User
Posts: 608
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim » 23 Aug 2017, 22:50

[3/2/2.1/3/2/0.1] with 0.(?=\d.\d)
[3/2/0.2.1/3/2/0.1] without
ChannelPositions/String2: 3/2/0.2.1 / 3/2/0.1
aka 7.1 / 5.1
it's not 5.2.1 channels, at least I have never heard of it ;)

from a test test I have:
https://wiki.videolan.org/DTS/
http://streams.videolan.org/misc/DTS-HD ... HD-HRA.mkv

kim
Power User
Posts: 608
Joined: 15 May 2014, 16:17

Re: Multiple audio tracks with different codecs and languages

Post by kim » 22 Jan 2018, 18:01

devster wrote: now you only need to fix the adding part
12.2 DTS Eng, 12.2 DTS Eng, 12.2 DTS Eng, 18.3 DTS Eng, 18.3 DTS Eng, 18.3 DTS Eng, 12.2 DTS Eng, 12.2 DTS Eng, 12.2 DTS Eng
12.2 DTS Eng, 7.1 TrueHD Eng, 5.1 AC3 Eng, 5.1 DTS Eng, 5.1 DTS Eng, 5.1 AC3 Eng, 5.1 AC3 Fra, 5.1 AC3 Ita, 5.1 AC3 Spa, 5.1 AC3 Nld, 5.1 AC3 Cat, 5.1 AC3 Spa, 5.1 AC3 Nld
@devster
Did you ever fix this problem (because of other user need help) ?
From: BabyRay
Recipient: kim
Hello,

hope you can help and sorry for my bad english :)
I use this for my Movies:

{ny} [{vf}] [{ import java.math.RoundingMode
import net.filebot.Language
audio.collect { au ->
def channels = any{ au['ChannelPositions/String2'].replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '') }{ au['Channel(s)_Original'] }{ au['Channel(s)'] }
def ch = channels.tokenize('\\/')*.toDouble()
.inject(0, { a, b -> a + b }).findAll { it > 0 }
.max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
def codec = any{ au['CodecID/Hint'] }{ au['Format'] }.replaceAll(/['`´‘’ʻ\p{Punct}\p{Space}]/, '')
return allOf{ch}{codec}{Language.findLanguage(au['Language']).ISO3.upperInitial()} }*.join(" ").join(", ") }]{fn =~ /ger|german/ ? '.ger' : fn =~ /eng|english/ ? '.eng' : null}{'.'+fn.match(/forced/)} {group}

When i click on File with DTS 7.1 i get DTS 11.2 !
And the part with the Subs is not correct. I cant explain, sorry.
Hope you can help
for now you can try this:

Code: Select all

{
audio.collect { au ->
def ch  = any{(0.0+audio.'ChannelPositionsString2'*.replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '')*.split(' / ')*.collect{ it.split('/')*.toBigDecimal().sum() }*.max().max()).toString()}{channels};
def codec = any{ au['CodecID/Hint'] }{ au['Format'] }.replaceAll(/['`´‘’ʻ\p{Punct}\p{Space}]/, '')
return allOf{ch}{codec}{au['Language/String3'].upper()} }*.join(" ").join(", ")
}
sample output:
7.1 DTS ENG, 7.1 TrueHD ENG, 7.1 AC3 ENG, 7.1 DTS ENG, 7.1 DTS ENG, 7.1 AC3 ENG, 7.1 AC3 FRA, 7.1 AC3 ITA, 7.1 AC3 SPA, 7.1 AC3 DUT, 7.1 AC3 CAT, 7.1 AC3 SPA, 7.1 AC3 DUT

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 22 Jan 2018, 23:03

I added .take(3) after the tokenize.

Code: Select all

{ import java.math.RoundingMode
  import net.filebot.Language
  // map Codec + Format Profile
  def mCFP = [ "AC3" : "AC3",
               "AC3+" : "E-AC3",
               "AAC LC LC" : "AAC-LC",
               "AAC LC SBR HE AAC LC" : "HE-AAC" ]
  def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ') }
  audio.collect { au ->
    def channels = any{ au['ChannelPositions/String2'] }{ au['Channel(s)_Original'] }{ au['Channel(s)'] } 
    def ch = channels.replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '')
                     .tokenize('\\/').take(3)*.toDouble()
                     .inject(0, { a, b -> a + b }).findAll { it > 0 }
                     .max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
    def codec = audioClean(any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] })
    def format = any{ au['CodecID/Hint'] }{ au['Format'] }
    def format_profile = { if ( au['Format_Profile'] != null) audioClean(au['Format_Profile']) else '' }
    def combined = allOf{codec}{format_profile}.join(' ')
    def stream = allOf
                   { ch }
                   { mCFP.get(combined, format) }
                   { Language.findLanguage(au['Language']).ISO3.upperInitial() }
    return stream }*.join(" ").join(", ") }
the audio map is incomplete (work in progress).
I only work in black and sometimes very, very dark grey. (Batman)

BabyRay
Posts: 5
Joined: 10 Jan 2018, 16:23

Re: Multiple audio tracks with different codecs and languages

Post by BabyRay » 07 Apr 2018, 15:01

Hi Devster,

i use this one to name my series:

Code: Select all

D:\Downloads\{n} - {'S'+s.pad(2)}E{e.pad(2)} - {t} [{vf}] 
[{ import java.math.RoundingMode
  import net.filebot.Language
  // map Codec + Format Profile
  def mCFP = [ "AC3" : "AC3",
               "AC3+" : "E-AC3",
               "AAC LC LC" : "AAC-LC",
               "AAC LC SBR HE AAC LC" : "HE-AAC" ]
  def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ') }
  audio.collect { au ->
    def channels = any{ au['ChannelPositions/String2'] }{ au['Channel(s)_Original'] }{ au['Channel(s)'] } 
    def ch = channels.replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '')
                     .tokenize('\\/').take(3)*.toDouble()
                     .inject(0, { a, b -> a + b }).findAll { it > 0 }
                     .max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
    def codec = audioClean(any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] })
    def format = any{ au['CodecID/Hint'] }{ au['Format'] }
    def format_profile = { if ( au['Format_Profile'] != null) audioClean(au['Format_Profile']) else '' }
    def combined = allOf{codec}{format_profile}.join(' ')
    def stream = allOf
                   { ch }
                   { mCFP.get(combined, format) }
                   { Language.findLanguage(au['Language']).ISO3.upperInitial() }
    return stream }*.join(" ").join(", ") }]{fn =~ /ger|german/ ? '.ger' : fn =~ /eng|english/ ? '.eng' : null}{'.'+fn.match(/forced/)} {group}
Still get 6.0,8.0 etc, instead of 5.1 or 7.1.
Can you help me please?

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 07 Apr 2018, 23:07

Not without a file to test it on.
However, while some files can be misinterpreted as 6.0, I never get 8.0.
I only work in black and sometimes very, very dark grey. (Batman)

BabyRay
Posts: 5
Joined: 10 Jan 2018, 16:23

Re: Multiple audio tracks with different codecs and languages

Post by BabyRay » 08 Apr 2018, 10:01

my mistake, mean 6.0 E-AC3 and 11.2 DTS.
No Files for testing? :(

User avatar
devster
Posts: 149
Joined: 06 Jun 2017, 22:56

Re: Multiple audio tracks with different codecs and languages

Post by devster » 08 Apr 2018, 11:18

I don't have that many, you could just pm me a few names and I'll get them. It's relevant because it's highly dependent on mediainfo and the specific file.
E-AC3 can be an issue because mediainfo sees the following:

Code: Select all

Channel positions                        : 3/2/1.0 3/2/0.1
and my format takes the first instead of the second bit. (resulting in 6.0)
I only work in black and sometimes very, very dark grey. (Batman)

User avatar
sighunter
Posts: 6
Joined: 26 Aug 2016, 08:08

Re: Multiple audio tracks with different codecs and languages

Post by sighunter » 13 Jun 2018, 14:45

thanks for all the work, this was exactly what I needed and could never have done alone

User avatar
sighunter
Posts: 6
Joined: 26 Aug 2016, 08:08

Re: Multiple audio tracks with different codecs and languages

Post by sighunter » 14 Jun 2018, 11:30

I added some more codecs to the Codec + Format Profile map, if anyone needs.

Code: Select all

  def mCFP = [ "AC3" : "AC3",
               "AC3+" : "E-AC3",
		"TrueHD" : "TrueHD",
		"TrueHD TrueHD+Atmos / TrueHD" : "TrueHD ATMOS",
               "DTS" : "DTS",
               "DTS HD HRA / Core" : "DTS-HD HRA",
               "DTS HD MA / Core" : "DTS-HD MA",
               "DTS HD X / MA / Core" : "DTS-X",
               "PCM" : "PCM",
               "FLAC" : "FLAC",
               "AAC LC LC" : "AAC-LC",
               "AAC LC SBR HE AAC LC" : "HE-AAC" ]
Some are redundant: DTS, PCM, FLAC, TrueHD are just there as reference.
They already show up as "DTS", "PCM", "FLAC", "TrueHD" anyway.

yob
Posts: 3
Joined: 03 Jul 2018, 22:32

Re: Multiple audio tracks with different codecs and languages

Post by yob » 03 Jul 2018, 22:37

devster wrote:
22 Jan 2018, 23:03
I added .take(3) after the tokenize.

Code: Select all

{ import java.math.RoundingMode
  import net.filebot.Language
  // map Codec + Format Profile
  def mCFP = [ "AC3" : "AC3",
               "AC3+" : "E-AC3",
               "AAC LC LC" : "AAC-LC",
               "AAC LC SBR HE AAC LC" : "HE-AAC" ]
  def audioClean = { it.replaceAll(/[\p{Pd}\p{Space}]/, ' ').replaceAll(/\p{Space}{2,}/, ' ') }
  audio.collect { au ->
    def channels = any{ au['ChannelPositions/String2'] }{ au['Channel(s)_Original'] }{ au['Channel(s)'] } 
    def ch = channels.replaceAll(/Object\sBased\s\/|0.(?=\d.\d)/, '')
                     .tokenize('\\/').take(3)*.toDouble()
                     .inject(0, { a, b -> a + b }).findAll { it > 0 }
                     .max().toBigDecimal().setScale(1, RoundingMode.HALF_UP).toString()
    def codec = audioClean(any{ au['CodecID/String'] }{ au['Codec/String'] }{ au['Codec'] })
    def format = any{ au['CodecID/Hint'] }{ au['Format'] }
    def format_profile = { if ( au['Format_Profile'] != null) audioClean(au['Format_Profile']) else '' }
    def combined = allOf{codec}{format_profile}.join(' ')
    def stream = allOf
                   { ch }
                   { mCFP.get(combined, format) }
                   { Language.findLanguage(au['Language']).ISO3.upperInitial() }
    return stream }*.join(" ").join(", ") }
the audio map is incomplete (work in progress).
How am I supposed to run this script?
I just installed Filebot for the first time and am a little confused.

So far I have:

Code: Select all

filebot -rename "G:\Meine Ablage\Plexy\DOWNLOAD\Black.Swan.2010.German.DTS.DL.1080p.BluRay.AVC.Remux-iNCEPTiON" --output "G:\Meine Ablage\Plexy\DOWNLOAD\Black.Swan.2010.German.DTS.DL.1080p.BluRay.AVC.Remux-iNCEPTiON" --format "{n.upperInitial().space('.')}.({y}).{'['+source+']'}{'['+vf+']'}{'['+ac+']'}{'['+channels+']'}{'['+vc.replace('Microsoft', 'VC-1')+']'}{any{n.findMatch(group) ? null : '-'+group}{'-'+fn.match(/(?<=[-])\w+$/)}}" --action test
Now I'd like to combine it with your script, so I get better details for audio. But I'm unable to find out how to insert your script.
Is this a groovy file, a arguments file or simple arguments (which would make it unreadable, cause of it's length :D) I tried all of those methods, probably just wrong, but none worked. :(
I'm sorry for the silly question. :)

User avatar
rednoah
The Source
Posts: 14306
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Multiple audio tracks with different codecs and languages

Post by rednoah » 04 Jul 2018, 01:50

:idea: Use the @file syntax for reading command-line arguments from external text files.
:idea: Please read the FAQ and How to Request Help.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest