Previously, I wrote about Counting Lines of Code in a given directory. Recently, I had a similar curiousity- “how long are all the video files in this folder?” This seemed to be a good fit for a Python script.
The main question, then, is how do we determine the length of a video file in Python? Once we have that problem solved, we can effectively use the same code as the CodeCount and “sum” all the lengths together in much the same way that the Code Count script sums all the line counts.
The most straightforward approach I discovered was using ffmpeg to retrieve video information, redirecting the output to a temp file, and then finding the listed Duration in that temp file. We then take that determined duration and parse it, and create a Python TimeDelta. We can use that TimeDelta, and sum all the TimeDelta’s of the files in question to determine the total run time of all the videos in the specified folders.
#! /usr/bin/env python
for root,subFolders,files in os.walk(folder):
for file in files:
tmpf = tempfile.NamedTemporaryFile()
fname = tmpf.name
sSystem = "D:\\programs\\ffmpeg\\static\\bin\\ffmpeg -i \"%s\" 2> %s" % (filepath, tmpf.name);
tmpf = open(fname)
lines = tmpf.readlines()
for l in lines:
l = l.strip()
getduration = re.search('Duration: (.*?),', l).group(0).split(':',1).strip(' ,')
timeparts = getduration.split(':') #hour,minute,second
if __name__ == '__main__':
searchfor = sys.argv
searchin = sys.argv
print("examining files matching " + searchfor + " in directory " + searchin)
for countthese in searchfolder(searchin,searchfor):
grablength = getVideoLength(countthese)
if grablength is not None:
totalcount = totalcount + getVideoLength(countthese)
print("total length:" + str(totalcount))
A bit of checking code to allow for the use of *.* to total all ffmpeg compatible video files rounds this out- the syntax is the same as the Code Counter- VidLength.py <FileMask> <directory< and it will display all the files it analyzes and then a total duration.
For quite some time I’ve been wrestling with a mysterious issue.
You see, I have several COM components. COM, is, to be usable from the various Script languages installed with windows. I encountered this some time ago when creating a small demonstration script file, something along the lines of the following, which simply showed a files size:
Set BCFS = CreateObject("BCFile.BCFSObject")
Set ffile = BCFS.GetFile(WScript.Arguments(1))
However, upon running it, I was greeted with the helpful dialog shown in figure 22-1.
For some reason or another, the ActiveX Object simply couldn’t be created (I gathered this after many long hours of research). My first “retry” was simple- I at first simply assumed that I had to run as administrator, so I started a command prompt as administrator, and ran it again.
This was getting to be annoying. I tried a equal script in JScript/ECMAScript or whatever the hell it’s called these days:
BCFS = new ActiveXObject("BCFile.BCFSObject");
ffile = BCFS.GetFile(WScript.Arguments);
It failed as well. so it wasn’t because of something I was doing wrong in the script. I then tried an alternative; I created a Visual Basic Project, and ran similar code.
It was able to create and use the object with absolutely no difficulty.
I was beginning to find this whole exercise at least as intriguing as it was frustrating. I decided to explore what happened with other operating Systems with VMWare. The script ran fine in Windows 2000 and Windows XP (assuming of course I had installed BCSearch or otherwise had BCFile.dll properly installed). However, it continued to fail. I went into a test frenzy. It failed on Windows 7 on both my laptop and desktop, worked in all my VMWare installations (including Vista) I was stymied.
Then, I ran it on two copies of Windows XP I had on my laptop. Windows XP Pro worked fine. Windows XP x64 did not.
So it was an architecture issue, I surmised. Going on that, I came to the realization that a 64-bit executable cannot instantiate a 32-bit COM object, at least, not an In-Process (DLL) COM object. This was likely the source of the error. I Ran a simple script with a msgbox() that would keep the Script runner running, and then opened Process Explorer.
Not surprisingly, the WScript.exe Process was 64-bit, this was the cause of my problems. the fix? Run the WScript or CScript in %systemroot%\syswow64\ instead. I did so, and the script ran without incident.