我在使用open cv和python錄制我的網路攝像頭時,在生成迷你視頻剪輯(每個都是10s的視頻剪輯)方面遇到了困難。
基本上,我想把攝像頭的視頻剪切成10S長度的片段并存盤在一個檔案夾中。 當我這樣做的時候,視頻片段被剪切,但當我檢查第一個視頻片段時,有100%的完整視頻。 第二段有大約75%的完整視頻,第三段有大約50%,等等。
所以我如何解決這個問題。 我將把我的孔代碼放在下面。希望你能幫助解決這個問題
。
camera = cv2.VideoCapture(0)
global rec, img, out
rec = 0
def gen_frames()。
global img
while True:
成功, img = camera.read()
def record(out)。
global rec, img
while(rec != False)。
time.sleep(0.05)
out.write(img)
@app.route('/requests',methods=['POST','GET'))
def tasks()。
if request.form.get('rec') == 'Start/Stop Recording':
global rec, img, out
rec= not rec
############### This Part work when manualy recode on and off ###############
# if rec:
# print("start")
# global out
# now=datetime.datetime.now()>
# fourcc = cv2.VideoWriter_fourcc(*'XVID')。
# p = os.path.sep.join(['clips', "vid_{}.avi".format(str(now).replace(":",')]])
# out = cv2.VideoWriter(p, fourcc, 25.0, size)
# thread = Thread(target = record, args=[out,])
# thread.start()
# if(rec==False):
# print("stop")
# out.release()
class TimerClass(threading.Thread)。
def __init__(self):
threading.Thread.__init__(self)
self.event = threading.Event()
def run(self)。
while (rec != False) and not self.event.is_set() 。
now=datetime.datetime.now()
fourcc = cv2.VideoWriter_fourcc(*'XVID'/span>)
p = os.path.sep.join(['clips', "vid_{}.avi". format(str(now).replace(":",'') ])
out = cv2.VideoWriter(p, fourcc, 25.0, size)
thread = Thread(target = record, args=[out,])
thread.start()
self.event.wait(10)
def stop(self)。
self.event.set()
tmr = TimerClass()
if(rec):
print("start"/span>)
tmr.start()
if(rec==False) 。
print("stop"/span>)
tmr.stop()
elif request.method=='get':
return render_template('index.html')
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', threaded=True)
uj5u.com熱心網友回復:
對我來說,問題是在TimerClass的回圈中,你每10秒創建一個新的執行緒,但你從來沒有停止前一個執行緒,它仍然記錄幀。我想直接在TimerClass中寫入幀,而不是使用另一個執行緒。
或者執行緒record()應該檢查時間并在10秒后停止。
我使用timedelta來計算何時停止記錄一個檔案并創建下一個檔案。我在TimerClass中這樣做,但你可以在record()中做類似的事情。
VideoWriter(..., 25.0)并不是用25fps來寫的,它只是為視頻播放器提供了如何快速顯示這個視頻的資訊。為了得到10秒的視頻,你需要睡眠0.04,因為1s / 25fps = 0.04或者你將不得不寫250幀(10s * 25fps = 250fps)。
因為代碼也需要一些時間來作業,我將不得不使用0.03而不是0.04來獲得10秒的視頻。
完整的作業代碼。
我使用render_template_string而不是render_template來獲得所有的檔案 - 每個人都可以簡單地復制和測驗它。
fromflask import Flask, Response, request, render_template, render_template_string
import cv2
import os
import datetime, time
import 執行緒
# global varaibles[/span]。
capture = False[/span
rec = False
out = None
img = None
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] =300
camera = cv2.VideoCapture(0)
frame_width = int(camera.get(3)
frame_height = int(camera.get(4)
size = (frame_width, frame_height)
os.makedirs('./shots', exist_ok=True)
os.makedirs('./clips', exist_ok=True)
def gen_frames() 。
global捕獲
global img
print('[DEBUG] gen_frames: start'/span>)
while True:
成功, img = camera.read()
if not success:
break not success.
if capture:
capture = False false
now = datetime.datetime.now()
filename = "shot_{}.png".format(str(now)。 replace(" :",'')
path = os.path.sep.join([' shots', filename])
print('[DEBUG] capture:'/span>, path)
cv2.imwrite(path, img)
frame = cv2.imencode('.jpg', img)[1] .tobytes()
yield (b'-frame
'
b'Content-Type: image/jpeg
' frame b' ')
')
@app.route('/video_feed'))
def video_feed()。
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/'))
def index()。
#return render_template('index.html')。
return render_template_string(''
轉到<a href="/requests">FORM</a>。
'')
# define class only once
class TimerClass(threading.Thread)。
def __init__(self):
threading.Thread.__init__(self)
self.event = threading.Event()
def run(self)。
seconds_10 = datetime.timedelta(seconds=10)
while rec and not self.event.is_set()。
now = datetime.datetime.now()
filename = "vid_{}.avi".format(str(now)。 replace(" :", '')
path = os.path.sep.join(['clips'/span>, filename])
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter(path, fourcc, 25.0, size)
end = now seconds_10
print('[DEBUG] end:'/span>, end)
while now < end and rec and not self.event.is_set() 。
if img is not None: # `img`可以是`numpy.array`所以它不能檢查`if img:`。
out.write(img)
time.sleep(0.03) # 1s / 25fps = 0.04 # 它需要一些時間來撰寫代碼。
now = datetime.datetime.now()
out.release()
def stop(self)。
self.event.set()
@app.route('/requests', methods=['POST', 'GET')) /span>
def tasks()。
global capture
global rec
print('[DEBUG] click:'/span>, request.form.get('click')
print('[DEBUG] rec :', request.form.get('rec')
if request.method == 'POST':
if request.form.get('click') == 'Capture':
if request.form.get('rec') == 'Start/Stop Recording':
rec = not rec
tmr = TimerClass()
if rec:
print("start"/span>)
tmr.start()
else:
print("stop")
tmr.stop()
#return render_template_string('index.html')
return render_template_string(''
<img src="/video_feed"><br/>
<form method="POST">
<button type="submit" name="click" value="Capture"> Capture</button>
<button type="submit" name="rec" value="Start/Stop Recording" >Start/Stop Recording</button>
</form>
'')
if __name__ == '__main__'/span>:
thread_cam = threading.Thread(target=gen_frames)
thread_cam.start()
app.run(host='0.0.0.0', threaded=True)
編輯:
與執行緒record()
def record(seconds)。
now = datetime.datetime.now()
filename = "vid_{}.avi".format(str(now). replace(" :", '')
path = os.path.sep.join(['clips'/span>, filename])
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter(path, fourcc, 25.0, size)
end = now datetime.timedelta(seconds=秒)
print('[DEBUG] end:'/span>, end)
while now < end and rec:
if img is not None: # `img`可以是`numpy.array`所以它不能檢查`if img:`。
out.write(img)
time.sleep(0.03) # 1s / 25fps = 0.04 # 它需要一些時間來撰寫代碼。
now = datetime.datetime.now()
out.release()
# 僅定義一次類
class TimerClass(threading.Thread)。
def __init__(self):
threading.Thread.__init__(self)
self.event = threading.Event()
def run(self)。
length = 10
while rec and not self.event.is_set()。
t = threading.Thread(target=record, args=(length,))
t.start()
self.event.wait(length)
def stop(self)。
self.event.set()
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/328640.html
標籤:
