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

Resources