Page 1 of 1

Fine-tuning bestBitRate output for audio codec

Posted: 03 Sep 2022, 15:33
by nartana
I've been very happy with the 'display best audio stream codec info' script Kim helped me create.

I'd like to discover how to fine-tune the best-audio-codec output re. periods (see Output example, below snippet).

Code: Select all

Movies/{vf}/{any{"$collection/($y) ${n.replace(':',' -')}"}{"${n.replace(':',' -')} ($y)"}}{'/' + {n.replace(':',' -')} + ' (' + y + ') '}{'(' + fn.matchAll(/Extended.|Ultimate.)?(Director.?s|Collector.?s|Theatrical|Ultimate|Final|Extended|Rogue|Special|Diamond|Despecialized|R.Rated|(\\d+th.)?Anniversary).(Cut|Edition|Version)|Extended|Remastered|Recut|Uncut|Uncensored|Unrated|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, " ") + ') '}
{tags.matchAll(/extended|uncensored|remastered|unrated|uncut|Theatrical|Theatrical.Cut|Theatrical.edition|3d|directors.cut|special.edition/)*.normalizePunctuation()*.upperInitial()*.lowerTrail().sort().unique().join(' - ')}{ minutes + 'mins [' }{vf =~ /2160p/ ? '4k' : HD}
{ ' [' + vf + ' @' + mbps.space('').lower() + '] '}

{
	def preferredLang = 'Eng'
	def useChFilter = false
	def filter = { [it.codec, it.ch, it.objects] }

	def codecList =
	[
	'MP3' : 'MP3',
	'PCM' : 'PCM',
	'AAC LC' : 'AAC',
	'AAC LC SBR' : 'AAC',
	'AAC LC SBR PS' : 'AAC',
	'AC 3' : 'AC3',
	'AC 3 Dep' : 'EAC3',
	'E AC 3' : 'EAC3',
	'E AC 3 JOC' : 'EAC3 Atmos',
	'AC 3 Dep JOC' : 'EAC3 Atmos',
	'AC 3 MLP FBA 16 ch' : 'TrueHD Dolby 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',
	'FLAC' : 'FLAC',
	'VORBIS' : 'Ogg Vorbis WHAT',
	'Vorbis' : 'Ogg Vorbis WHAT WHAT'
	]

	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() }

any{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' : any {au['default'][0].toBoolean() }{ audio.size == 1 ? true : '' },
		'codec' : codecList.get(combined, 'Add to "' + combined + '" codecList'), 'combined' : combined, 'ch' : useChFilter ? chFilter : ch,
		'bitrate' : any{ toInt(au.BitRate) }{ toInt(au.BitRate_Maximum) }{null}, 'frameRate' : any{ au.FrameRate.toDouble() * ch.toDouble() }{null} ]	
		return audioStreams

	}

	def addToList = audioStreams.codec.findAll{ it.contains('Add to') }.unique().sort()
	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 bestFrameRate = oneStream(audioStreams.findAll{ it.frameRate == audioStreams.frameRate.max() })
	def defaultStream = oneStream(audioStreams.findAll{ it.default == true })
	def bestPreferredGer = any{audioStreams.findAll{it.lang == preferredGer }.sort{it.bitrate}.reverse().collect{ filter(it) }*.minus(null).unique().get(0).join(' ')}{''}
	def bestPreferredEng = any{audioStreams.findAll{it.lang == preferredEng }.sort{it.bitrate}.reverse().collect{ filter(it) }*.minus(null).unique().get(0).join(' ')}{''}

bestBitRate.space('.') }
		{'NO_AUDIO'}
}

{'/' + {n.replace(':',' -')} + ' (' + y + ') '}{ vf }{' ★' + hdr + '★'}{ minutes + 'mins [' }{vf =~ /2160p/ ? '4k' : HD}{ ' [' + vf + ' @' + mbps.space('').lower() + '] '}{' [' + af + ']'}
Folder Name Output:
Olympus Has Fallen (2013) 119mins [4K @71mbps] DTS-HD.MA.5.1

Desired Folder Name Output:
Olympus Has Fallen (2013) 119mins [4K @71mbps] DTS-HD MA 5.1

Attempted Script Changes:
I tried using a space instead of a period, i.e. bestBitRate.space(' '). This removes the period from "5.1" and makes it "5 1" which is undesired.

P.S. I never get edition tags (i.e. 'Final Cut') to show up. Do you see anything wrong with the tags string in my script?

P.P.S. I realize it’s not necessarily good form to have "@" in my filenames, but I like it.

Thank-you for considering these questions.

Re: Fine-tuning bestBitRate output for audio codec

Posted: 04 Sep 2022, 20:04
by nartana
As I was. (Specifically, I was an idiot).

I solved the main question myself, by accident.

I edited this snippet:

Code: Select all

bestBitRate.space('.')
I made it like this:

Code: Select all

bestBitRate
And then it did what I wanted... err, what it's supposed to do.

However!

I still can't get tags to work. For example, no "Directors Cut," or "Extended Edition," et al.

Can you see any issues in the snippets (example, original post) relating to tags?

Re: Fine-tuning bestBitRate output for audio codec

Posted: 05 Sep 2022, 12:01
by rednoah
{tags} doesn't just work? (if not, please paste an example file path)

Re: Fine-tuning bestBitRate output for audio codec

Posted: 05 Sep 2022, 14:42
by nartana
Thanks for the wknd reply rednoah.

Yes, I got {tags} to work yesterday. I had begun trying various {tags} variables you suggested in other threads. Suddenly, success. I've no idea why - obviously, a PICNIC type situation. ha.

And, by using {tags.first() } I got rid of the brackets and replaced them with stars (desired).

Below is the script that works for me, now:

Code: Select all

…Media/Movies/{vf}/{any{"$collection/($y) ${n.replace(':',' -')}"}{"${n.replace(':',' -')} ($y)"}}{'/' + {n.replace(':',' -')} + ' (' + y + ') '}{' ★' + tags.first() + '★ '}{ minutes + 'mins '}{'['}{vf =~ /2160p/ ? '4K' : hd}{' ' + mbps.lower() + '] ' + '[' + bitdepth + 'bit] '}

{
   def preferredLang = 'Eng'
   def useChFilter = false
   def filter = { [it.codec, it.ch, it.objects] }

   def codecList =
   [
   'MP3' : 'MP3',
   'PCM' : 'PCM',
   'AAC LC' : 'AAC',
   'AAC LC SBR' : 'AAC',
   'AAC LC SBR PS' : 'AAC',
   'AC 3' : 'AC3',
   'AC 3 Dep' : 'EAC3',
   'E AC 3' : 'EAC3',
   'E AC 3 JOC' : 'EAC3 Atmos',
   'AC 3 Dep JOC' : 'EAC3 Atmos',
   'AC 3 MLP FBA 16 ch' : 'TrueHD Dolby 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',
   'FLAC' : 'FLAC',
   'VORBIS' : 'Ogg Vorbis WHAT',
   'Vorbis' : 'Ogg Vorbis WHAT WHAT'
   ]

   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() }

any{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' : any {au['default'][0].toBoolean() }{ audio.size == 1 ? true : '' },
       'codec' : codecList.get(combined, 'Add to "' + combined + '" codecList'), 'combined' : combined, 'ch' : useChFilter ? chFilter : ch,
       'bitrate' : any{ toInt(au.BitRate) }{ toInt(au.BitRate_Maximum) }{null}, 'frameRate' : any{ au.FrameRate.toDouble() * ch.toDouble() }{null} ]   
       return audioStreams

   }

   def addToList = audioStreams.codec.findAll{ it.contains('Add to') }.unique().sort()
   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 bestFrameRate = oneStream(audioStreams.findAll{ it.frameRate == audioStreams.frameRate.max() })
   def defaultStream = oneStream(audioStreams.findAll{ it.default == true })
   def bestPreferredGer = any{audioStreams.findAll{it.lang == preferredGer }.sort{it.bitrate}.reverse().collect{ filter(it) }*.minus(null).unique().get(0).join(' ')}{''}
   def bestPreferredEng = any{audioStreams.findAll{it.lang == preferredEng }.sort{it.bitrate}.reverse().collect{ filter(it) }*.minus(null).unique().get(0).join(' ')}{''}

bestBitRate }
       {'NO_AUDIO'}
}

{'/' + {n.replace(':',' -')} + ' (' + y + ') '}{ minutes + 'mins '}{'[' + hd + ' ' + mbps.lower() + '] '}{'[' + hdr + '] '}{af}
Successful output (subdirectory name):
Independence Day (1996) ★Extended★ 153mins [4K 40 mbps] [10bit] DTS-HD MA 7.1

Successful Output (file name):
Independence Day (1996) 153mins [UHD 40 mbps] [HDR10] 8ch.mkv

Any 'clean-up' suggestions always welcome. For my feral scripting.

Sorry for posting questions when I should've dug in more, first.

Thanks for continuing to evolve this software.