Adding language names with codecs

All about user-defined episode / movie / file name format expressions
Post Reply
callten
Posts: 19
Joined: 17 Feb 2014, 10:48

Adding language names with codecs

Post by callten »

Hi again. I deal with multilanguage tv shows and movies a *lot*, I rip English audio and then always take French and Dutch if they are present on the Blu-ray. I take the DTS core if the source is DTS-HD MA and the AC3 core if it's TrueHD. Sometimes, shows/movies with a DTS-HD MA main language will have AC3 foreign languages.

Now, I want to know, at a glance, which languages (and their codec) are present in each mkv. For the sake of keeping the filename as short as possible, I'm trying to get it to list them as follows:

Code: Select all

<movie name, year, resolution, source etc>.DTS.en.fr.nl.<video codec>
This bit of code accomplishes this:

Code: Select all

{ac.match(/DTS/)}{'.'+audios.language[0]}{'.'+audios.language[1].replaceAll("null", "")}{'.'+audios.language[2].replaceAll("null", "")}
but only if the codec for all languages is DTS.

What I *really* would love, if there are languages in more than one codec is for it to output something like:

Code: Select all

<movie name, year, resolution, source etc>.DTS.en.AC3.fr.nl.<video codec>
It would ideally only mention the codec once and then list each language in that codec after the codec name. I thought of maybe somehow nesting the audios.language parts inside the braces with the ac.match part and having something like:

Code: Select all

{ac.match(/DTS/){'.'+audios.language[0]}{'.'+audios.language[1].replaceAll("null", "")}{'.'+audios.language[2].replaceAll("null", "")}}{ac.match(/AC3/){'.'+audios.language[0]}{'.'+audios.language[1].replaceAll("null", "")}{'.'+audios.language[2].replaceAll("null", "")}}
but this doesn't work (probably for obvious reasons, I'm still finding my way around groovy scripting). For this to work, it would need to be able to identify the codec for each language and only add the language that matched either DTS or AC3 in the appropriate "section". I don't know if I can do iteration like this in groovy or not. :(

The only languages I really care about are en, fr and nl but some movies have foreign audio only (Sin Nombre, Seven Samurai, etc etc) so I will just include all 2-letter track names that I find.

Now, is this beyond the scope of what Filebot/groovy can do? Any help would be much appreciated. :)
User avatar
rednoah
The Source
Posts: 22923
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Adding language names with codecs

Post by rednoah »

I don't have multi-audio multi-codec file like this to test with but i'm pretty there's nothing that groovy can't do :P

This is what you do.

... actually code is more compact

Here you go:

Code: Select all

{audios.groupBy{ it.Codec }.collect{ c, a -> [c] + a*.Language }.flatten().join('.')}
:idea: Please read the FAQ and How to Request Help.
callten
Posts: 19
Joined: 17 Feb 2014, 10:48

Re: Adding language names with codecs

Post by callten »

Ok, I've just put something together so I will write this post and then test that out.

I've got a rip I did of Despicable Me 2 with 3 audio tracks (all DTS) and I used:

Code: Select all

{'.'+audios.codec[0].replaceAll("null", "")}{'.'+audios.language[0].replaceAll("null", "")}{'.'+audios.codec[1].replaceAll("null", "")}{'.'+audios.language[1].replaceAll("null", "")}{'.'+audios.codec[2].replaceAll("null", "")}{'.'+audios.language[2].replaceAll("null", "")}
...which gave me:

Code: Select all

DTS.en.DTS.fr.DTS.nl
...which is exactly what I want, except for the repetition of DTS each time, I'm after:

Code: Select all

DTS.en.fr.nl
The above bit of code I put together does exactly what it's supposed to because I asked for the codec each time.

Ok, off to try your suggestion... :)
callten
Posts: 19
Joined: 17 Feb 2014, 10:48

Re: Adding language names with codecs

Post by callten »

Ok, you are in fact a certifiable genius. It works perfectly. I should never have doubted groovy's capabilities! :)

Is there a guide to some of the more intricate groovy syntax that you could point me at (the stuff that's relevant to FileBot anyway)? I know it's very similar to Java but that doesn't help me much because I don't know Java. :P

Or could you walk me through your statement with the bits I haven't encountered in my groovy adventures yet? Specifically "it.x" and "collect{ c, a -> [c] + a*.Language"?

Thank you for the solution, again.
User avatar
rednoah
The Source
Posts: 22923
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Adding language names with codecs

Post by rednoah »

I guess this stuff is considered too basic cause it's not really in the docs, there should be blogs and other resources though.

It's all really just List, Map and Closure that make the magic happen. Also why Groovy is so much nicer to work with Collections than Java.

Maybe this can get you started:
http://groovy.codehaus.org/Collections
http://groovy.codehaus.org/Closures
http://groovy.codehaus.org/groovy-jdk/j ... ction.html

As for your questions:

"it" is the default name for variables passed into closures, e.g. when iterating lists.

{ a, c -> ... } is specifying a closure with 2 parameters and giving them names. So { ... } is really just short syntax for { it -> ... } ;)

The collect parts iterators through the map, each key-value pair gets transformed to another object, in this case a list where the 1. element is the codec followed by list of language, [c] makes object c into list with one element c so we can use + operator to add another list. The *. is for getting properties of objects in a list as a list.
:idea: Please read the FAQ and How to Request Help.
callten
Posts: 19
Joined: 17 Feb 2014, 10:48

Re: Adding language names with codecs

Post by callten »

Awesome stuff, thanks.

I've added a bit to list subtitle languages in square brackets too, using flatten and join:

Code: Select all

{n.space('.').replaceAll(/[()]+/).replaceAll(/[,]+/)}{'.'+y}{'.'+vf.match(/720[pP]|1080[pP]/)}{'.'+source.replaceAll('(?i)BluRay', 'Blu-ray')}{'.'+audios.groupBy{ it.Codec }.collect{ c, a -> [c] + a*.Language }.flatten().join('.')}{'.['+texts.language.flatten().join('.')+']'}{'.'+vc}
...which gives me:

Code: Select all

Ben-Hur.1959.1080p.Blu-ray.DTS.en.AC3.fr.[en.fr.nl].x264.mkv
Captain.Phillips.2013.1080p.Blu-ray.DTS.en.AC3.fr.[en.fr].x264.mkv
Finding.Nemo.2003.1080p.Blu-ray.AC3.en.fr.[en.fr].x264.mkv
Gomorrah.2008.1080p.Blu-ray.DTS.it.[en].x264.mkv
Gravity.2013.1080p.Blu-ray.DTS.en.AC3.fr.[en.fr].x264.mkv
Princess.Mononoke.1997.1080p.Blu-ray.DTS.ja.AC3.en.fr.[ja.en.fr].x264.mkv
RoboCop.1987.1080p.Blu-ray.DTS.en.fr.[en.fr.nl].x264.mkv
Runner.Runner.2013.1080p.Blu-ray.DTS.en.fr.[en.fr.nl].x264.mkv
Rush.2013.1080p.Blu-ray.DTS.en.fr.[en.fr].x264.mkv
The.Road.2009.1080p.Blu-ray.DTS.en.x264.mkv
Very cool! :)
DevXen
Power User
Posts: 164
Joined: 12 Oct 2014, 21:15

Re: Adding language names with codecs

Post by DevXen »

Hmm. Does anyone know how I would match each of thses:

Code: Select all

{audios.groupBy{ it.language }.collect{ c, a -> a*.language}.flatten()})
results to a csv file. (to get the full language names example: en;English)

this is the csv file; csv('C:/FileBot Settings/All/Locales.csv').get()

I just have been having issues getting it to work with the group/collect above. the closest i've been able to get is a result of [null, null]
Post Reply