I am trying to complete this part of my program. In this section, I am trying to speed up or slow down a video based on a factor variable. Once it's done, I use moviepy to turn it into a VideoFileClip, then I delete the file.
if factor <= 2:
system("ffmpeg -i " + paths[dex] + " -vf setpts=" + str(vfactor) + "*PTS -an ./Media/Videos/temp.mp4")
system("ffmpeg -i " + paths[dex] + " -filter:a atempo=" + str(factor) + " -vn ./Media/ShortSounds/temp.mp3")
elif 2 < factor < 4:
factor = round(sqrt(factor), 1)
system("ffmpeg -i " + paths[dex] + " -vf setpts=" + str(vfactor) + "*PTS,setpts=" + str(vfactor) + "*PTS -an ./Media/Videos/temp.mp4")
system("ffmpeg -i " + paths[dex] + " -filter:a atempo=" + str(factor) + ",atempo=" + str(factor) + " -vn ./Media/ShortSounds/temp.mp3")
elif factor > 4:
raise Exception("File " + paths[dex] + " is too long.")
t = VideoFileClip("./Media/Videos/temp.mp4")
t.audio = AudioFileClip("./Media/Videos/temp.mp3")
templist.append(t)
remove("./Media/Videos/temp.mp4")
However, when the code gets to the deletion command, it has the following error:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: './Media/Videos/temp.mp4'
What's strange is, I can see the temp.mp4 file, and it runs just fine. I never get this error while manually running the temp.mp4 file.
I have tried the following:
Waiting 5, 10, and 20 seconds before deleting the file.
Running "taskkill -f -im ffmpeg.exe" before deleting the file
I went through the debugger, and right before the deletion, I checked in task manager to see if ffmpeg was still running, and it wasn't.
Do you guys have any idea what could be holding this up? My code worked previously when I was trying to just do audio, but I am trying it with video and this is happening.
Related
EDIT 1 - added more code
I'm not sure that proc.communicate was needed, it was one of the suggestions I found from some other stackoverflow code.(Sorry I was tired last night and didn't think too much before asking the question.)
I should add that I am not an experienced coder (mechanical engineer) as you can probably tell from my code
In my Gui I have a button to call a subprocess
The subprocess (screenshot-cmd.exe) creates a png of a cropped screen shot but it won't actually produce the file until there is an error or if the button click event is over.
This makes me think that the subprocess is not actually run until the event is finished
I want to call the process several times after a single button press and move the files that it produces after each one is produced
if I use proc.wait(), the process hangs indefinitely.
How do I stop this?
# function to take a single image called 'fileName' and place it in directory 'dir'
def takeImage(dir,fileName):
# calculate the view to capture to get the whole display window in.
clientRect = win32gui.GetClientRect(win32gui.GetForegroundWindow())
windowRect = win32gui.GetWindowRect(win32gui.GetForegroundWindow())
print(windowRect)
windowSize = [windowRect[2]-windowRect[0],windowRect[3]-windowRect[1]]
print(windowSize)
print(clientRect)
diffSize = [windowSize[0] -clientRect[2], windowSize[1] - clientRect[3]]
lrbBorder = diffSize[0]/2
topBorder = diffSize[1] - lrbBorder
print("sizeDiff = " + str(diffSize))
windowName = win32gui.GetWindowText(win32gui.GetForegroundWindow())
handleId = win32gui.GetForegroundWindow()
leftMar = designLabel.GetPosition()[0] + lrbBorder
topMar = designLabel.GetPosition()[1] + topBorder + designLabel.GetSize()[1]
rightMar = leftMar + scene.width
bottMar = topMar+scene.height
margins = [leftMar,topMar,rightMar,bottMar]
print(margins)
# now print the view.
#command_line = r"screenshot-cmd -wt '" + windowName + "' -rc " + str(margins[0]) + " " + str(margins[1]) + " " + str(margins[2]) + " " + str(margins[3]) + " -o " + fileName
command_line = r"screenshot-cmd -wt '" + windowName + "' -rc " + str(margins[0]) + " " + str(margins[1]) + " " + str(margins[2]) + " " + str(margins[3]) + " -o " + fileName
print(command_line)
args = shlex.split(command_line)
proc = subprocess.Popen(args)
proc.wait()
wx.Yield()
if not os.path.isdir(dir):
os.makedirs(dir)
newPath = os.path.join(dir,fileName)
if os.path.exists(newPath):
os.remove(newPath)
oldPath = os.path.join(os.getcwd(), fileName)
print("Old Path: " + oldPath)
print("Exists: " + str(os.path.exists(oldPath)))
shutil.move(oldPath,newPath)
return
#event called upon clicking 'takeTenImag' button
def takeTenImgE(evt):
global designNo
global workingDirectory
global numDesigns
fileNameRoot = "test_"
fileExtention = ".png"
# check there are at least 10 designs
if numDesigns > 9 and os.path.exists(workingDirectory):
# find directory path to put images in
dir = os.path.join(workingDirectory, "images")
# for each design
for x in range(10):
print("design =" + str(designNo))
fileName = fileNameRoot + str(designNo) + fileExtention
print("------------------")
print("for x = " + str(x) + " " + fileName)
# create image and save
print(dir)
takeImage(dir,fileName)
#move to next design
wx.PostEvent(forwardDesign, wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, forwardDesign.GetId()) )
wx.Yield()
print("design =" + str(designNo))
return
takeTenImg = wx.Button(p, label='Take Ten Images', pos=(rb + visScaleText.GetSize()[0]+10,takeImg.GetPosition()[1]+5 +takeImg.GetSize()[1]), size = (100,30))
takeTenImg.Bind(wx.EVT_BUTTON, takeTenImgE)
https://code.google.com/p/screenshot-cmd/
Barnaby, you may be over-complicating your subprocess use. Popen is typically used for when you need to communicate with the process during the time it is running. From the sound of it, you don't need to do that, so might want to use a higher level function. See the docs on subprocess' various invocations, and perhaps try using the call method. You'll need shell=True, as detailed in SO questions such as this one.
I've found that the error is in my calling of subprocess.
I was using:
command_line = r"screenshot-cmd -wt '" + windowName + ...."
args = shlex.split(command_line)
subprocess.call(args,shell=True)
changing this to:
command_line = r"screenshot-cmd -wt '" + windowName + ...."
subprocess.call(command_line,shell=True)
solves the hang.
What is peculiar is that both options work when not inside a wx button click event(i.e. a python script launched from the command line), but only the second works when inside the wx button click event.
If anyone could enlighten me why that would be most appreciated.
EDIT:
upon further investigation, the hang is caused by trying to specify the active window in screenshot-cmd.
To solve this I find the position of the window using
windowRect = win32gui.GetWindowRect(win32gui.GetForegroundWindow())
and then use screenshot-cmd without specifying a window.
This solves all issues although it is unclear why this causes problems
I have a string that I build then pass to pexpect:
command = "for i in `python /tmp/"+ cecUser + "_getSyslogs.py " + startString + " " + endString + " " + myDir + "`;do gzcat /emslogs/archive/" + myDir + "/$i | grep " + node + " | egrep -v \"" + filteredWords + "\" >> /tmp/" + syslogFile + ";done"
p.sendline(command)
If filteredWords = "No LMA address", the script runs fine.
If filteredWords = "No LMA address|CLISess", the script fails.
What am I missing? I tried to escape the | by preceding with \ and that didn't help. I actually tried a whole slew of different combinations and the script still fails. What is even odder is the logging output from p.logfile looks fine:
$ for i in `python /tmp/getSyslogs.py 20141227120000 20141228120000 local1`;do gzcat /emslogs/archive/local1/$i | grep ALPRGAGQPN2 | egrep -v "No LMA address|CLISess" >> /tmp/1419900585.83_ALPRGAGQPN2_syslogs.txt;done
If I cut'n'paste that line on the target machine, it works no problem. There is just something about the pipe in the egrep that is messing up when passed to p.sendline.
please refer following code, which creates batch file for executing certain programs synchronously. but after execution of first file, the program stops and asks whether the batch to be continued. This is causing a delay for user input. Since i wish to run several files overnight, the program waits for user input. Could anyone help me with this error ?
import os
from subprocess import call
version = "0.1"
os.system('CLS')
print("////////////////////////////////////////////////")
print("// LS-DYNA Simulation Start Script, V" + version + " //")
print("////////////////////////////////////////////////\n")
input_flag = 0
while input_flag == 0:
solver_type_string = raw_input("Use single or double precision solver (s/d)?")
if solver_type_string == "s":
solver_type_string = "ls971_s_R5.1.1_winx64_p.exe"
print("Choosen Solver: " + solver_type_string + "\n")
input_flag = 1
elif solver_type_string == "d":
solver_type_string = "ls971_d_R5.1.1_winx64_p.exe"
print("Choosen Solver: " + solver_type_string + "\n")
input_flag = 1
else:
print("Invalid input!\n")
current_path = os.path.dirname(os.path.abspath(__file__))
solver_path = "C:\Programme\LSDyna-971.1\program\\" + solver_type_string
batch_file = open("sim_start.bat", "w")
batch_file.write("#echo off\n")
sim_counter = 0
for (path, dirs, files) in os.walk(current_path):
for sim_file in files:
if sim_file.endswith((".k", ".dyn")):
sim_counter = sim_counter + 1
sim_path = path
print("Found: \'" + sim_file + "\'")
batch_file.write("pushd " + sim_path + "\\\n")
batch_file.write(solver_path + " i=" + sim_path + "\\" + sim_file + "\n")
print "\nDone! Found ", sim_counter, " simulation files in total."
batch_file.close()
print "\nStarting LS-DYNA batch run...\n"
call(current_path + "\sim_start.bat")
The created file looks like
#echo off
pushd E:\Shah\CPW\t25_nw100_amp25_ptr35_matDC04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw100_amp25_ptr35_matDC04\t25_nw100_amp25_ptr35_matDC04.dyn
pushd E:\Shah\CPW\t25_nw100_amp30_ptr40_matDC04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw100_amp30_ptr40_matDC04\t25_nw100_amp30_ptr40_matDC04.dyn
pushd E:\Shah\CPW\t25_nw10_amp15_ptr25_matDC04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw10_amp15_ptr25_matDC04\t25_nw10_amp15_ptr25_matDC04.dyn
pushd E:\Shah\CPW\t25_nw10_amp20_ptr30_matDC04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw10_amp20_ptr30_matDC04\t25_nw10_amp20_ptr30_matDC04.dyn
pushd E:\Shah\CPW\t25_nw10_amp25_ptr35_matDC04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw10_amp25_ptr35_matDC04\t25_nw10_amp25_ptr35_matDC04.dyn
pushd E:\Shah\CPW\t25_nw10_amp30_ptr40_matDC04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw10_amp30_ptr40_matDC04\t25_nw10_amp30_ptr40_matDC04.dyn
pushd E:\Shah\CPW\t25_nw30_amp15_ptr25_matDc04\
C:\Programme\LSDyna-971.1\program\ls971_d_R5.1.1_winx64_p.exe i=E:\Shah\CPW\t25_nw30_amp15_ptr25_matDc04\t25_nw30_amp15_ptr25_matDc04.dyn
After some research, I can conclude that, when we press 'ctrl + c' during the batch run (i was pressing ctrl + c to check the execution time of ls dyna program ), the window of "whether you want to terminate the batch prohgram" appears and program waits for user input..
final="cacls " + "E:/" + "\"" + list1[2] + " " + list1[3] + "\"" + " /p " + str
os.system(final)
I am trying to set permission to a folder Using Python but while running this command , User input needs to be provided too i.e
it asks ARE YOU SURE(Y/N) and the user needs to enter "Y" or "N"
Is there any way to use python to send the user input "Y" along with the above code?
pro = subprocess.Popen(final,shell=True, stdin=subprocess.PIPE)
pro.communicate(bytes("Y\r\n",'utf-8'))
I have added the following code . The program exits without setting the permission.
http://jimmyg.org/blog/2009/working-with-python-subprocess.html#writing-to-standard-input
Try using the subprocess module
import subprocess
cmd = ["cacls", "E:/" + list1[2], list1[3], "/p", str]
pro = subprocess.Popen(final, stdin=subprocess.PIPE)
pro.communicate("y\r\n")
As a smart programmer, use PBS
Then, the code is:
from pbs import type as echo# Isn't it echo for Windows? If not, use the correct one
script = Command("/path/to/cacls ")
print script(echo("Y"), ("E:/" + "\"" + list1[2] + " " + list1[3] + "\"" + " /p " + str).split())
final="cacls " + "E:/" + "\"" + list1[2] + " " + list1[3] + "\"" + " /p " + str
pro = subprocess.Popen(final,shell=True, stdin=subprocess.PIPE)
pro.communicate(bytes("Y\r\n",'utf-8'))
Trying to set permission to a folder Using Python but while running this command , User input needs to be provided too i.e
it asks ARE YOU SURE(Y/N) and the user needs to enter "Y" or "N"
The above code is not setting the permission.
This was the question i had asked before:
Python code to send command through command line
As a smart programmer, use PBS
Then, the code is:
from pbs import type as echo# Isn't it echo for Windows? If not, use the correct one
script = Command("/path/to/cacls ")
print script(echo("Y"), ("E:/" + "\"" + list1[2] + " " + list1[3] + "\"" + " /p " + str).split())