這邊是一個視訊撥放器範例
在這邊我先簡單定義一個視訊撥放面板,
def init_frameviewer(self):
定義常和寬
self.LABEL_WIDTH = 540
self.LABEL_HEIGHT = 330
影片來源控制面板
self.StreamCtrlPanel = tk.LabelFrame(self.parent ,
text="Stream Control Panel",
font=('Courier', 9))
self.StreamCtrlPanel.pack(side=tk.TOP, expand=tk.NO, fill = tk.X)
選擇local camera的單選紐
self.selStr = tk.StringVar()
fromlocalCam = tk.Radiobutton(self.StreamCtrlPanel,
text = "Local Camera",
font=('Courier', 9),
variable = self.selStr,
value = "From Local Camera",
command = self.init_VideoCapture)
fromlocalCam.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
輸入其他裝置來源網址的變數
self.DEV_VIDEO_NAME= tk.StringVar()
self.DEV_VIDEO_NAME.set("視訊網址")
選擇其他裝置視訊來源的單選紐
fromdevCam = tk.Radiobutton(self.StreamCtrlPanel,
text = "Device Camera",
font=('Courier', 9),
variable = self.selStr,
value = "From Device Camera",
command = self.init_VideoCapture)
fromdevCam.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
輸入其他裝置來源的輸入方塊
self.DeviceVideoPath= tk.Entry(self.StreamCtrlPanel ,
textvariable=self.DEV_VIDEO_NAME,
width = 10)
self.DeviceVideoPath.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
選擇local端的視訊影片
fromlocalVideofile = tk.Radiobutton(self.StreamCtrlPanel,
text = "Local Video File",
font=('Courier', 9),
variable = self.selStr,
value = "From Local Video File",
command = self.load_video)
fromlocalVideofile.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
輸入local端影片變數
self.LOCAL_VIDEO_NAME = tk.StringVar()
輸入local端影片來源輸入方塊
self.LocalVideoPath= tk.Entry(self.StreamCtrlPanel ,
textvariable=self.LOCAL_VIDEO_NAME,
width = 10)
self.LocalVideoPath.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
影片操作面板
self.VideoCtrlPanel = tk.LabelFrame(self.parent ,
text="VideoControl Panel",
font=('Courier', 9))
self.VideoCtrlPanel.pack(side=tk.TOP, expand=tk.NO, fill = tk.X)
播放鍵
showframebutton = tk.Button(self.VideoCtrlPanel,
text = "PLAY",
font=('Courier', 9),
command = self.show_frame)
showframebutton.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
停止鍵
capreleabutton = tk.Button(self.VideoCtrlPanel,
text ="STOP",
font=('Courier', 9),
command = self.cap_release)
capreleabutton.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
把影片分割成一張張frame的功能鍵
split_framebutton = tk.Button(self.VideoCtrlPanel,
text ="Split",
font=('Courier', 9),
command = self.split_frame)
split_framebutton.pack(side=tk.LEFT, expand=tk.NO, fill = tk.X)
承載撥放影片的frame版面
self.streamplay_tab = tk.Frame(self.parent)
self.streamplay_tab.pack(side = tk.LEFT, expand=tk.YES, fill=tk.BOTH)
定義self.stream為承載影片的載體,使用物件label
self.stream = tk.Label(self.streamplay_tab,
width=self.LABEL_WIDTH,
height=self.LABEL_HEIGHT)
self.stream.pack(side=tk.LEFT, expand=tk.NO, fill = tk.BOTH)
撥放影片
def show_frame(self, event = None):
_, frame = self.cap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
frame = cv2.resize(frame,(self.LABEL_WIDTH,self.LABEL_HEIGHT))
img = Image.fromarray(frame)
imgtk = ImageTk.PhotoImage(image=img)
self.stream.imgtk = imgtk
self.stream.configure(image=imgtk)
self.stream.after(15, self.show_frame)
停止視訊
def cap_release(self, event = None):
self.cap.release()
self.stream.configure(image=圖片檔路徑)
切分視訊成為frame
def split_frame(self, event = None):
if self.selStr.get() =="From Local Camera":
self.cap = cv2.VideoCapture(0)
elif self.selStr.get() =="From Local Video File":
self.cap = cv2.VideoCapture(self.localvideoname)
#調整預設影像大小,預設值很大,很吃效能
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.LABEL_WIDTH)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.LABEL_HEIGHT)
if not os.path.exists(os.getcwd()+"/split_frame"):
os.mkdir("split_frame")
while(self.cap.isOpened()): #當攝影機打開時,對每個frame進行偵測
T = int(100*time.time())
#讀出frame資訊
ret, frame = self.cap.read()
#輸出到畫面
cv2.imshow("Split frame", frame)
cv2.imwrite('split_frame/'+str(T)+'.jpg', frame)
#如果按下ESC键,就退出
if cv2.waitKey(1) == 27: break
#釋放記憶體
self.cap.release()
#關閉所有視窗
cv2.destroyAllWindows()
選擇視訊來源
def init_VideoCapture(self, event = None):
if self.selStr.get() =="From Local Camera":
self.cap = cv2.VideoCapture(0)
elif self.selStr.get() =="From Local Video File":
self.cap = cv2.VideoCapture(self.localvideoname)
elif self.selStr.get() =="From Device Camera":
self.cap = cv2.VideoCapture(self.DEV_VIDEO_NAME.get())
以下是選取視訊來源程序上的差異:
打開資料夾載入視訊檔
def load_video(self, event = None):
self.localvideoname = filedialog.askopenfilename(
initialdir = "/",
title = "Select file",
filetypes = (("mp4 files","*.mp4*"),
("all files","*.*")))
self.LOCAL_VIDEO_NAME.set(self.localvideoname)
self.init_VideoCapture()
在製作視訊工具時,我想在畫面上打映出時間戳記,在show_frame()內部可以利用下面的程式碼...
# timestamp
Time = time.time()
# datetime 物件
local_time = time.ctime(Time)
# write the time information on the frame
cv2.putText(frame, str(local_time), (10, 10),
1,
1,
(255,255,255),
1,
0)