Saturday, December 16, 2017

#1 2017-10-17 05:37:35 am

Lunchbox
Member
Registered: 2015-01-15
Posts: 2

Script to remux mkv to mp4 using ffmpeg issues

Hi

I need a script that searches a folder for mkv files and remux them to mp4 container using ffmpeg.

I've got this old script, I've been using for years. But it uses Handbrake and is very slow, and I still loose some of the quality.

Here is the script I've been using on my old mac mini. But I can't "see" what I need to do to get it to work as needed.

--on adding folder items to this_folder after receiving these_items
with timeout of (720 * 60) seconds
    tell application "Finder"
        --Get all AVI and MKV files that have no label color yet, meaning it hasn't been processed
        set allFiles to every file of entire contents of (folder "Multimedia:TV") whose ((name extension is "avi" or name extension is "mkv") and label index is 0)
       
        --Repeat for all files in above folder
        repeat with i from 1 to number of items in allFiles
            set currentFile to (item i of allFiles)
           
            try
                --Set to gray label to indicate processing
                set label index of currentFile to 7
               
                --Assemble original and new file paths
                set origFilepath to quoted form of POSIX path of (currentFile as text)
                set newFilepath to (characters 1 thru -5 of origFilepath as string) & "mp4'"
               
                --Start the conversion
                set shellCommand to "nice /Applications/HandBrakeCLI -i " & origFilepath & " -o " & newFilepath & " -e x264  -q 18.0 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,none -R Auto,Auto -D 0.0,0.0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback ffac3 -f mp4 -4 --decomb --loose-anamorphic --modulus 2 -m --x264-preset medium --h264-profile high --h264-level 4.1"
                do shell script shellCommand
               
                --Set the label to green in case file deletion fails
                set label index of currentFile to 6
               
                --Remove the old file
                set shellCommand to "rm -f " & origFilepath
                do shell script shellCommand
            on error errmsg
                --Set the label to red to indicate failure
                set label index of currentFile to 6
            end try
        end repeat
    end tell
end timeout
--end adding folder items to


Filed under: mkv, ffmpeg, MP4, remux

Offline

 

#2 2017-10-17 03:38:58 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4457

Re: Script to remux mkv to mp4 using ffmpeg issues

Hi.

Besides the time taken to do the conversions (about which I don't know enough to be able to offer any advice), a possible major bottleneck in the script is the Finder's 'entire contents' command, which can take a very long time if there are a large number of items and is here picking out 'files' and applying a 'whose' filter with three conditions.

One alternative is to use a 'find' shell script to find AVI and MKV files, although the Finder would still have to check the label indices:

Applescript:

-- Original Finder reference used to identify the root folder as it's not clear if it's in a volume called "Multimedia" or in a folder of that name on the user's desktop.
tell application "Finder" to set rootFolderAlias to folder "Multimedia:TV" as alias

--Get POSIX paths to all AVI and MKV files. Label indices will be checked below.        
set allPaths to paragraphs of (do shell script "find -f " & quoted form of POSIX path of rootFolderAlias & " \\( -name '*.avi' -or -name '*.AVI' -or -name '*.mkv' -or -name '*.MKV' \\)")

-- Repeat for all paths obtained.
repeat with thisPath in allPaths
   set currentFile to (POSIX file thisPath) as alias
   
   -- Get this file's label index. If it's 0, the file hasn't been processed yet.
   tell application "Finder" to set currentLabelIndex to label index of currentFile
   if (currentLabelIndex is 0) then
       try
           --Set to gray label to indicate processing
           tell application "Finder" to set label index of currentFile to 7
           
           --Assemble original and new file paths
           set origFilePath to quoted form of thisPath
           set newFilepath to (text 1 thru -5 of origFilePath) & "mp4'"
           
           --Start the conversion
           set shellCommand to "nice /Applications/HandBrakeCLI -i " & origFilePath & " -o " & newFilepath & " -e x264 -q 18.0 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,none -R Auto,Auto -D 0.0,0.0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback ffac3 -f mp4 -4 --decomb --loose-anamorphic --modulus 2 -m --x264-preset medium --h264-profile high --h264-level 4.1"
           do shell script shellCommand
           
           --Set the label to green in case file deletion fails
           tell application "Finder" to set label index of currentFile to 6
           
           --Remove the old file
           set shellCommand to "rm -f " & origFilePath
           do shell script shellCommand
       on error errmsg
           --Set the label to green to indicate failure
           tell application "Finder" to set label index of currentFile to 6
       end try
   end if
end repeat

Another way involves the use of ASObjC, which can also be used instead of the Finder to check and set the labels:

Applescript:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

-- Original Finder reference used to identify the root folder as it's not clear if it's in a volume called "Multimedia" or in a folder of that name on the user's desktop.
tell application "Finder" to set rootFolderAlias to folder "Multimedia:TV" as alias

set |⌘| to current application
set rootFolderURL to |⌘|'s class "NSURL"'s fileURLWithPath:(POSIX path of rootFolderAlias)
set fileManager to |⌘|'s class "NSFileManager"'s defaultManager()
set labelNumberKey to |⌘|'s NSURLLabelNumberKey

-- Get URLs to the folder's entire visible contents along with the relevant label numbers.
set allURLs to (fileManager's enumeratorAtURL:(rootFolderURL) includingPropertiesForKeys:({labelNumberKey}) options:(|⌘|'s NSDirectoryEnumerationSkipsHiddenFiles) errorHandler:(missing value))'s allObjects()
-- Filter the items to just those whose name extensions are "avi" or "mkv".
set AVIOrMKVURLPredicate to |⌘|'s class "NSPredicate"'s predicateWithFormat:("pathExtension.lowercaseString IN {'avi','mkv'}")
set AVIOrMKVURLs to allURLs's filteredArrayUsingPredicate:(AVIOrMKVURLPredicate)

-- Repeat for all the AVI and MKV URLs obtained.
repeat with origURL in AVIOrMKVURLs
   -- Get this URL's label number. If it's 0, the file hasn't been processed yet.
   set {success, labelNumber} to (origURL's getResourceValue:(reference) forKey:(labelNumberKey) |error|:(missing value))
   if ((labelNumber is not missing value) and (labelNumber as integer is 0)) then
       try
           --Set to gray label to indicate processing
           -- Apart from 0, label numbers are 8 minus the equivalent Finder label indices.
           tell origURL to setResourceValue:(8 - 7) forKey:(labelNumberKey) |error|:(missing value)
           
           --Assemble original and new file paths
           set origFilePath to origURL's |path|()
           set newFilePath to (origFilePath's stringByDeletingPathExtension()'s stringByAppendingPathExtension:("mp4"))
           
           --Start the conversion.
           set shellCommand to "nice /Applications/HandBrakeCLI -i " & quoted form of (origFilePath as text) & " -o " & quoted form of (newFilePath as text) & " -e x264 -q 18.0 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,none -R Auto,Auto -D 0.0,0.0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback ffac3 -f mp4 -4 --decomb --loose-anamorphic --modulus 2 -m --x264-preset medium --h264-profile high --h264-level 4.1"
           do shell script shellCommand
           
           --Set the label to green in case file deletion fails
           tell origURL to setResourceValue:(8 - 6) forKey:(labelNumberKey) |error|:(missing value)
           
           --Remove the old file
           tell fileManager to removeItemAtURL:(origURL) |error|:(missing value)
       on error errmsg
           --Set the label to green to indicate failure
           tell origURL to setResourceValue:(8 - 6) forKey:(labelNumberKey) |error|:(missing value)
       end try
   end if
end repeat

As in the original script, the 'try' block isn't entirely foolproof in either of these alternatives, as one of the possible reasons for not being able to delete a file is that it's locked — in which case you won't be able to set its label index either. The ASObjC commands don't generate AppleScript errors if they're unsuccessful, but errors can be generated based on their results if desired. It didn't seem worth the bother here.


NG

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)