Loop Over Video Files in Folder to get video length - applescript
I have the following which returns how many seconds a selected video file is.
However I was after a way to just give it the movie folder and for it to then loop through all subdirectories and find all video file types.
Once it has these I would like to list the video length in "1 hour 53 seconds" type format as "7990 seconds" isn't too helpful.
Thanks
set macPath to (choose file) as text
tell application "System Events"
set ts to time scale of movie file macPath
set dur to duration of movie file macPath
set movieTime to dur / ts
end tell
You have several sub-questions involved in your question.
1) How do I get all of the files in a folder, including the sub folders
2) how do I filter that list to only include video files
3) How do I loop through that list of video files and extract information from each and
4) How do I convert seconds into a useable string of words
Normally I would ask that you break it down into those individual questions because it's a large task for someone to write the whole thing for you. However, in this case you're lucky because I had done this before myself... so you can have my script. I put lots of comments in the code to help you learn how it works.
-- I found these extensions for video files here http://www.fileinfo.net/filetypes/video
-- we can check the file extensions of a file against this list to evaluate if it's a video file
set video_ext_list to {"3g2", "3gp", "3gp2", "3gpp", "3mm", "60d", "aep", "ajp", "amv", "asf", "asx", "avb", "avi", "avs", "bik", "bix", "box", "byu", "cvc", "dce", "dif", "dir", "divx", "dv", "dvr-ms", "dxr", "eye", "fcp", "flc", "fli", "flv", "flx", "gl", "grasp", "gvi", "gvp", "ifo", "imovieproject", "ivf", "ivs", "izz", "izzy", "lsf", "lsx", "m1v", "m2v", "m4e", "m4u", "m4v", "mjp", "mkv", "moov", "mov", "movie", "mp4", "mpe", "mpeg", "mpg", "mpv2", "msh", "mswmm", "mvb", "mvc", "nvc", "ogm", "omf", "prproj", "prx", "qt", "qtch", "rm", "rmvb", "rp", "rts", "sbk", "scm", "smil", "smv", "spl", "srt", "ssm", "svi", "swf", "swi", "tivo", "ts", "vdo", "vf", "vfw", "vid", "viewlet", "viv", "vivo", "vob", "vro", "wm", "wmd", "wmv", "wmx", "wvx", "yuv"}
-- get the folder to check
set f to choose folder
-- notice the use of "entire contents" to also go through subfolders of f
-- use a "whose" filter to find only the video files
tell application "Finder"
set vidFiles to (files of entire contents of f whose name extension is in video_ext_list) as alias list
end tell
-- use a repeat loop to loop over a list of something
set vidList to {} -- this is where we store the information as we loop over the files
repeat with aFile in vidFiles
-- get some information from aFile
tell application "System Events"
set vidFile to movie file (aFile as text)
set ts to time scale of vidFile
set dur to duration of vidFile
end tell
-- add the information to the "storage" list we made earlier
set end of vidList to {POSIX path of aFile, secs_to_hms(dur / ts)}
end repeat
return vidList
(*=================== SUBROUTINES ===================*)
-- convert seconds into a string of words
-- the use of "mod" and "div" here makes it easy
-- we also make sure that each value is at least 2 places long to make it look nicer
on secs_to_hms(the_secs)
set timeString to ""
set hr to the_secs div hours
if hr is not 0 then set timeString to timeString & (text -2 thru -1 of ("0" & (hr as text))) & " hours "
set min to the_secs mod hours div minutes
if min is not 0 then set timeString to timeString & (text -2 thru -1 of ("0" & (min as text))) & " minutes "
set sec to the_secs mod minutes div 1
if sec is not 0 then
set fraction to text 2 thru 3 of ((100 + the_secs mod 1 * 100) as text)
set timeString to timeString & (sec as text) & "." & fraction & " seconds"
end if
if timeString ends with space then set timeString to text 1 thru -2 of timeString
return timeString
end secs_to_hms
I came across this post because I wanted to have a log of video files in a folder; something I could import in a spreadsheet, also to calculate the total duration but not only.
The posted script didn't work for me so I ended up importing the folder in Final Cut Pro, doing Batch Export on the folder and than File > Export > Batch List, which resulted in a plain text file I could import in a spreadsheet as the start of a log and to calculate the total duration.
Perhaps this helps others.
Related
Applescript to sort files into folder based on British financial year
I'm looking for way to move files based on UK financial year (runs from 6th April -5th April). Files are named in pattern as 2014-08-26_Asda_lunch.pdf 2016-03-20_Tesco_sationary.pdf The File needs to be moved to folders which are named, and so on FY 2014-15 FY 2015-16 Just wondering if applescript/ shell script or automator action would help to achieve this. Also interface with hazel wud be even better Thanks in advance I have tried to modify the script My first aim is get month right, then wud try dates; the Output for Script File 2019-07-26_Tesco_stationary -> FY 2020 ( expected FY 2019-20) File 2019-03-15_Sainsbury -> FY 2019 ( expected FY 2018-19) Please advise, also any pointers to add date in sorting wud be helpful Thank you set savedDelimiters to AppleScript's text item delimiters set AppleScript's text item delimiters to {"-"} tell application "Finder" set filename to name of theFile end tell set expenseYear to (first text item of filename) as number set expenseMonth to (second text item of filename) as number set expenseDate to (third text item of filename) as number -- Get the last two characters of the Year set AppleScript's text item delimiters to savedDelimiters set lastTwoCharactersOfYear to (characters 3 thru 4 of (expenseYear as text)) set RoundedExpYear to (lastTwoCharactersOfYear as text) as number if expenseMonth ≥ 4 then set LongString to expenseYear set ShortString to RoundedExpYear + 1 else set LongString to expenseYear - 1 set ShortString to RoundedExpYear end if set returnText to "FY" & " " & LongString & "-" & ShortString
There are many ways to parse dates but since your format is always the same (yyyy-mm-dd_xxxx) I used the easiest way. In script below the handler GetFY returns directly the format you're looking for "FY YYYY-YYYY" when you give parameter your file name: set Fname to "2014-03-05_xxxx" -- value to test set myfolder to GetFy(Fname) log "myfolder=" & myfolder on GetFy(Fname) -- return FY-(FY+1) based on Fname as YYYY-MM-DD_xxxxxx set myear to (text 1 thru 4 of Fname) as integer set mmonth to (text 6 thru 7 of Fname) as integer set mday to (text 9 thru 10 of Fname) as integer if mmonth < 4 then set Fy to myear - 1 if mmonth = 4 then set Fy to myear - ((mday ≤ 5) as integer) if mmonth > 4 then set Fy to myear return "FY " & Fy & "-" & (Fy + 1) end GetFy
Spotify giving wrong value of current track (AppleScript)
I am currently trying to make an application that gets the duration of the current song playing in Spotify. To do this I am using AppleScript. Here is my code: tell application "Spotify" return the duration of the current track end tell The length of the song is 2.52 minutes, the code is telling me 172026 seconds. By looking at the return value, it looks like it is returning the milliseconds and not the seconds of the track length. This I can fix easily by doing milliseconds*1000. The problem is 172026ms is not 2.52mins, instead it is 2.8671mins. How am I meant to get the true value of the song duration? Here is the Spotify AppleScript documentation: track n : A Spotify track. duration (integer, r/o) : The length of the track in seconds.
Just found that I needed to do a little bit of maths. Here is the code: tell application "Spotify" set tM to round (((duration of current track) / 1000) / 60) rounding down set tS to round (((duration of current track) / 1000) mod 60) rounding down set myTime to ((tM as text) & "," & tS as text) return myTime end tell Thanks to dronir for his code at https://github.com/dronir/SpotifyControl
You can also use the following code to read song & artist name (if you need it): "inline": "if application \"Spotify\" is running then\rtell application \"Spotify\"\rreturn \" \" & (get artist of current track) & \" – \" & (get name of current track)\rend tell\rend if\rreturn \"\"\r" (thanks to Toxblh from https://github.com/Toxblh/MTMR/blob/master/Resources/aadi_vs_anand.json)
Get date added of Finder items in Applescript
I can get files by date modified using this bit of code: get (files of entire contents of folder "Macintosh HD:General Music:05 Reggae:" whose modification date is less than ((current date)) - modDate * days) but I can't seem to get their date added (nor is it listed in Applescript dictionary for Finder that I can see). This is weird, 'cause I can do a smart folder that uses this property. Any idea on how to get files who were added within 15 days? Otherwise I'm doing loads of weird stuff with GUI at the moment and I'd like to automate it further. Thanks Tardy
You can search Spotlight's metadata with the mdfind command, use the kMDItemDateAdded key: set _15daysAgo to -15 * days -- number of seconds set tFolder to quoted form of POSIX path of "Macintosh HD:General Music:05 Reggae:" -- find files, not folders do shell script "mdfind -onlyin " & tFolder & " 'kMDItemDateAdded>$time.now(" & _15daysAgo & ") && ! kMDItemContentType == public.folder'" set tFiles to paragraphs of the result repeat with i in tFiles tell i to set contents to i as POSIX file as alias end repeat tFiles -- list of files who were added within 15 days Or, use the methods of the NSFileManager Class to get the NSURLAddedToDirectoryDateKey of the files (require Yosemite or El Capitan), Here's the AppleScript: set _15daysAgo to -15 * days -- number of seconds set f to POSIX path of "Macintosh HD:General Music:05 Reggae:" do shell script "/usr/bin/python -c 'import sys; from Foundation import NSFileManager, NSURL, NSDate, NSDirectoryEnumerationSkipsHiddenFiles def procFolder(tDir): p = dfM.contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_(tDir, myKeys, NSDirectoryEnumerationSkipsHiddenFiles, None)[0] for f in p: myDict, error=f.resourceValuesForKeys_error_(myKeys, None) if error is None: if (myDict.get(\"NSURLIsDirectoryKey\")): procFolder(f) elif (myDict.get(\"NSURLAddedToDirectoryDateKey\").compare_(d) == 1): print f.path().encode(\"utf8\") fold=NSURL.fileURLWithPath_isDirectory_(sys.argv[1].decode(\"utf8\"), True) dfM=NSFileManager.defaultManager() d=NSDate.dateWithTimeIntervalSinceNow_(" & _15daysAgo & ") myKeys=[\"NSURLIsDirectoryKey\", \"NSURLAddedToDirectoryDateKey\"] procFolder(fold)' " & f set tFiles to paragraphs of the result repeat with i in tFiles tell i to set contents to i as POSIX file as alias end repeat tFiles -- list of files who were added within 15 days
Mavericks AppleScript count every desktop always returns 1
I've got a script taken from GitHub that is supposed to set the wallpaper of every desktop to a certain image depending on the time of day. (I have modified it from the original code to include more time ranges, issue shows in both versions) The script attempts to count the number of desktops in order to change more than just the current desktop. It does this by first telling System Events the following set theDesktops to a reference to every desktop And then, in order to loop through every desktop, it does the following: if ((count theDesktops) > 1) then repeat with x from 2 to (count theDesktops) --some code removed, see full code below end repeat end if The issues is that count theDesktops always returns a 1, no matter how many desktops there are, as seen in the following screenshot. http://ss.kobitate.com/2013-12-28_0922_2.png What can be done to fix this? Here is the full code (* Script by Philip Hutchison, April 2013 http://pipwerks.com MIT license http://pipwerks.mit-license.org/ This script assumes: 1. You have a folder named "Wallpapers" in your Pictures folder 2. You have a subfolder named "Time of Day" in Wallpapers 3. You have six subfolders inside "Time of Day", with names that match the variables below. * If you decide to use different folder names, you must change the variables to match the new folder names 4. You have images inside each folder For example: /Users/YOUR_USER_NAME/Pictures/Wallpapers/Time of Day/Afternoon Early/image.jpg GeekTool can execute this script for you at specified intervals. Use this line in the command field: osascript ~/Pictures/Wallpapers/Time\ of\ Day/wallpaper.scpt *) -- BEGIN USER CONFIGURATION -- supply folder names set morningEarly to "Morning Early" set morningLate to "Morning Late" set afternoonEarly to "Afternoon Early" set afternoonLate to "Afternoon Late" set eveningEarly to "Evening Early" set eveningLate to "Evening Late" set nightEarly to "Night Early" set nightLate to "Night Late" -- for multiple monitor support. -- set to true to display the same image on all desktops, false to show unique images on each desktop set useSamePictureAcrossDisplays to true -- END USER CONFIGURATION -- get current hour set h to hours of (current date) -- set default periodOfDay set periodOfDay to nightLate -- change value of periodOfDay based on current time if (h > 6 and h < 8) then set periodOfDay to morningEarly else if (h ≥ 8 and h < 10) then set periodOfDay to morningLate else if (h ≥ 10 and h < 12) then set periodOfDay to afternoonEarly else if (h ≥ 12 and h < 16) then set periodOfDay to afternoonLate else if (h ≥ 16 and h < 18) then set periodOfDay to eveningEarly else if (h ≥ 18 and h < 20) then set periodOfDay to eveningLate else if (h ≥ 20 and h < 22) then set periodOfDay to nightEarly else if (h ≥ 22) then set periodOfDay to nightLate end if -- helper function ("handler") for getting random image on getImage(folderName) tell application "Finder" return some file of folder ("Pictures:Wallpapers:Time of Day:" & folderName) of home as text end tell end getImage tell application "Finder" -- wrapped in a try block for error suppression try -- determine which picture to use for main display set mainDisplayPicture to my getImage(periodOfDay) -- set the picture for additional monitors, if applicable tell application "System Events" -- get a reference to all desktops set theDesktops to a reference to every desktop -- handle additional desktops if ((count theDesktops) > 1) then -- loop through all desktops (beginning with the second desktop) repeat with x from 2 to (count theDesktops) -- determine which image to use if (useSamePictureAcrossDisplays is false) then set secondaryDisplayPicture to my getImage(periodOfDay) else set secondaryDisplayPicture to my mainDisplayPicture end if -- apply image to desktop set picture of item x of the theDesktops to secondaryDisplayPicture end repeat end if end tell -- set the primary monitor's picture -- due to a Finder quirk, this has to be done AFTER setting the other displays set desktop picture to mainDisplayPicture end try end tell Edit: Fixed an unrelated mistake I found in the code
This seems to be fixed now. I remember testing this when #KobiTate posted it. I am now on 10.9.1 but not sure when it was fixed tell application "System Events" set theDesktops to count of (a reference to every desktop) set theDesktops2 to count every desktop end tell log "count of (a reference to every desktop) = " & theDesktops log "count every desktop = " & theDesktops2 Returns: (count of (a reference to every desktop) = 2) (count every desktop = 2)
Applescript to repeat complete script for files in a folder
I have managed to get all this code together now and just need the last step to work. Any help would be greatly appreciated. I have setup this script to open an .xlsx file in a folder, change the date, save it then PDF to another folder. It then creates a mail by looking up the client code (found in the excel file) to subsequently look for this code in a Database.xlsx file and return the e-mail address of the client and add it to the "To" field in mail. It then attaches the newly created PDF to this mail and I can just click and send. The script stops after the first .xlsx file has been opened, just so I can check the details is correct before it PDF's and creates the mail. My question is: How do I get this process to repeat for each file in the initial folder? I have tried the repeat function, but to no avail. Any help would be greatly appreciated. Thank you. --Complete script for updating invoice, saving (as PDF too in seperate folder) and e-mailing invoices --Select the first file in a folder and then repeat for the next set theFolder to POSIX path of (choose folder with prompt "Choose Folder containing .xlsx invoices") set theFolderList to list folder theFolder without invisibles repeat with x from 1 to count of theFolderList set theFile to theFolder & item x of theFolderList set theNewFile to theFolder & theFile tell application "Microsoft Excel" activate open theFile set ActiveClientCode to value of range ("B1") end tell --Change date of one cell to date of next month tell application "Microsoft Excel" activate open "/Users/pienaar0/Documents/AdminAssist/" & ActiveClientCode & ".xlsx" set d to value of cell ("A1") set d to my MonthAdd(d) set value of cell ("A1") to d end tell on MonthAdd(d) set m to ((month of d as integer) + 1) set ddd to day of d if m > 12 then set m to m - 12 set year of d to (year of d) + 1 end if if {m} is in {4, 6, 9, 11} and ddd = 31 then --AppleScript treats "Apr 31" as May 1, set day of d to 30 end if set month of d to m if m = 2 and month of d as integer = 3 then --AppleScript treats "Feb 31" as Mar 3, set day of d to 1 -- Mar 1 set d to d - (1 * days) -- last day of Feb end if return d end MonthAdd property dialog_timeout : 36000 display dialog "Make sure the invoice is correct before clicking OK" buttons {"OK"} giving up after dialog_timeout set the user_choice to the button returned of the result --Save document and PDF tell application "Microsoft Excel" save active workbook save active workbook in "Macintosh HD:Users:pienaar0:Documents:AdminAssistPDF:" & ActiveClientCode & ".pdf" as PDF file format end tell --Find e-mail address, and Name in Database (Check filepath and ranges) tell application "Microsoft Excel" open "Users/pienaar0/Documents/Database.xlsx" set searchRange to range ("D2:D5") set foundRange to find searchRange what ActiveClientCode with match case set fRow to first row index of foundRange set ClientEmail to value of range ("C" & fRow as text) set ClientFirstname to value of range ("A" & fRow as text) (* do something with the foundRange *) end tell --Create e-mail tell application "Mail" set theMessage to make new outgoing message with properties {visible:true, subject:"Your monthly invoice", content:"Dear " & ClientFirstname & ", I trust this mail finds you well? Please find attached your monthly invoice for your immediate consideration. Regards, AdminAssist "} set message signature of theMessage to signature "Replies & Forwards" delay 1 tell content of theMessage make new attachment with properties {file name:"/Users/pienaar0/Documents/AdminAssist/PDF/" & ActiveClientCode & " Sheet1.pdf"} tell theMessage make new to recipient at end of to recipients with properties {address:ClientEmail} end tell end tell end tell end repeat
You need to move your handler outside of the repeat block: property dialog_timeout : 36000 --Complete script for updating invoice, saving (as PDF too in seperate folder) and e-mailing invoices --Select the first file in a folder and then repeat for the next set theFolder to POSIX path of (choose folder with prompt "Choose Folder containing .xlsx invoices") tell application "System Events" to set theFolderList to name of every file of folder theFolder whose visible is true repeat with x from 1 to count of theFolderList set theFile to theFolder & item x of theFolderList set theNewFile to theFolder & theFile tell application "Microsoft Excel" activate open theFile set ActiveClientCode to value of range ("B1") end tell --Change date of one cell to date of next month tell application "Microsoft Excel" activate open "/Users/pienaar0/Documents/AdminAssist/" & ActiveClientCode & ".xlsx" set d to value of cell ("A1") set d to my MonthAdd(d) set value of cell ("A1") to d end tell display dialog "Make sure the invoice is correct before clicking OK" buttons {"OK"} giving up after dialog_timeout set the user_choice to the button returned of the result --Save document and PDF tell application "Microsoft Excel" save active workbook save active workbook in "Macintosh HD:Users:pienaar0:Documents:AdminAssistPDF:" & ActiveClientCode & ".pdf" as PDF file format end tell --Find e-mail address, and Name in Database (Check filepath and ranges) tell application "Microsoft Excel" open "Users/pienaar0/Documents/Database.xlsx" set searchRange to range ("D2:D5") set foundRange to find searchRange what ActiveClientCode with match case set fRow to first row index of foundRange set ClientEmail to value of range ("C" & fRow as text) set ClientFirstname to value of range ("A" & fRow as text) (* do something with the foundRange *) end tell --Create e-mail tell application "Mail" set theMessage to make new outgoing message with properties {visible:true, subject:"Your monthly invoice", content:"Dear " & ClientFirstname & ", I trust this mail finds you well? Please find attached your monthly invoice for your immediate consideration. Regards, AdminAssist "} set message signature of theMessage to signature "Replies & Forwards" delay 1 tell content of theMessage make new attachment with properties {file name:"/Users/pienaar0/Documents/AdminAssist/PDF/" & ActiveClientCode & " Sheet1.pdf"} tell theMessage make new to recipient at end of to recipients with properties {address:ClientEmail} end tell end tell end tell end repeat on MonthAdd(d) set m to ((month of d as integer) + 1) set ddd to day of d if m > 12 then set m to m - 12 set year of d to (year of d) + 1 end if if {m} is in {4, 6, 9, 11} and ddd = 31 then --AppleScript treats "Apr 31" as May 1, set day of d to 30 end if set month of d to m if m = 2 and month of d as integer = 3 then --AppleScript treats "Feb 31" as Mar 3, set day of d to 1 -- Mar 1 set d to d - (1 * days) -- last day of Feb end if return d end MonthAdd