Hi,
I’m writing a Draft compositing template script, and I’m running into a file locking issue.
I wrap my encoding section in a try/catch and on catching I want to delete the file that has just been worked on. The code is as follows :
def delete_output(self):
if (os.path.isfile(self.theOutput)):
print (TAG+"Deleting the output file")
f = open(self.theOutput)
f.close()
os.remove(self.theOutput)
if (not os.path.isfile(self.theOutput)):
print (TAG+"Output file deleted successfully")
else:
print (TAG+"Failed to delete the output file")
def comp(self):
self.encoder = Draft.VideoEncoder( self.theOutput , 25, self.outWidth, self.outHeight, codec="H264" )
try:
for frameNumber in self.frames:
#read frames, do the comp...
self.encoder.EncodeNextFrame( myFrameA )
self.encoder.FinalizeEncoding()
except Exception as e:
self.encoder.FinalizeEncoding()
print (TAG+"Exception caught during compositing.")
print e
self.delete_output()
raise
However, I’m running into
WindowsError: [Error 32] The process cannot access the file because it is being used by another process: <path to the output>
My questions are therefore:
- Does Draft.VideoEncoder.FinalizeEncoding() close the file and release all handles?
- Can you suggest any way of ensuring the file is not locked?
Cheers,
Voy
Hi Voy!
Would it be possible for you to check if your movie named “theOutput” (created in an earlier execution of your script) is already open in another application (such as QuickTime) when you run your script?
Thanks!
Julie
Hi Julie, (Thanks for a quick answer!)
Just a note:
I do not create self.theOutput in the earlier part of the script, I assume is created at the time I create the encoder:
self.encoder = Draft.VideoEncoder( self.theOutput , 25, self.outWidth, self.outHeight, codec="H264" )
And as for your question:
I don’t have a way of ensuring such action isn’t taken, as the files are visible to all artists and as such could be open, however I can give a pretty confident assumption this is not happening.
-
Firstly, the Draft jobs take normally less than a minute and are not live monitored by our artists as they come out - they normally get picked up hours later.
-
Secondly, the error is appearing on quite a big number of draft jobs that throw exceptions during compositing (in majority of cases due to an input file missing). I’d really doubt anyone could keep on opening these straight away.
On the other hand it could be some automated monitoring that’s picking it up, maybe antivirus? Anything I should look for that you can think of?
Cheers,
Voy
Hi there,
Here’s what I was specifically thinking about…
Say you first run your script to create the movie: “shot1_2015-10-12.mov”. Then, an artist has a look at that movie and keeps it open in a certain application. Later, someone run your script again to create another movie with the exact same name: “shot1_2015-10-12.mov” (with the previous created movie still open in the application), an error occurs and your script tries to delete the movie “shot1_2015-10-12.mov”. Then, it’s totally possible to get the error “WindowsError: [Error 32]” (I reproduced exactly what I just described on my own machine with your script and Quick Time, and got this exact error message).
Of course, the issue might come from somewhere else. I just wanted to discard that possibility first… Today is an holidays in Canada so I might just be able to get to the bottom of this tomorrow… Sorry!
Kind regards,
Julie
Hey Julie,
I see your point. Thing is, before starting encoding, the script checks for the first available name, therefore avoiding writing to a file that’s already been created. As such, it should never write to a file that’s already existing, making it hardly possible (as I described in the previous reply) to open a file that is being, or will be encoded.
If “shot1_2015-10-12_v004.mov” has been created and is looked at by the artist, then the next time my script runs, it will generate “shot1_2015-10-12_v005.mov”.
Only situation I can think of is if two machines execute this script at the very same moment and check_output() would produce a same result. But given the probability of such accident is very low and the error appears quite often, I’d assume this is not the case.
Just in case, following is the auto-naming function:
def check_output(self):
j = 0
while (self.outName[-(j+1):].isdigit()):
j += 1
if (j == 0):
onlyName = self.outName
else:
onlyName = self.outName[:-j]
i = 1
while os.path.exists(self.theOutput):
i += 1
if (i > 1000000):
print (TAG+" ERR: check_output : loop overflow.")
break
newName = onlyName+(str(i).zfill(j))+self.outExt
self.theOutput = os.path.join(self.outFolder, newName)
Enjoy your holidays in that case!
Cheers,
Voy
Hi Voy,
I had some time today to play around with your script. It turns out that you are totally right, Draft doesn’t close the output file correctly. This bug was introduced in Draft 1.2.1 and will be fixed in the next Draft release.
In the mean time, how would you feel about not deleting the output movie (removing the call to self.delete_output() in your except block) and let Draft overwrites the movie (with same output filename) until it gets through all the frames without errors? I know it’s not ideal and it would be temporary, but would it work for now?
I’m very sorry for the inconvenience,
Julie
Hey Julie,
Thanks for your reply and good job finding that bug!
Unfortunately, it is quite essential we create the output names dynamically and clean them out on exceptions. Without this system our folders get filled up with .mov files that contain no data and make it far more difficult to find the needed quicktime.
Waiting for the next Draft then!
Cheers
Voy