日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python在tk界面播放本地视频_tkinter做一个本地视频播放器(2)——弹幕

發(fā)布時間:2023/12/14 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python在tk界面播放本地视频_tkinter做一个本地视频播放器(2)——弹幕 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前文我們已經(jīng)完成了一個集暫停、倍速、顯示進度條功能為一體的視頻播放器,今天我們再來增加一個新的功能——發(fā)送彈幕。

tkinter播放視頻的原理,就是讀取每一幀的圖片,然后刷新畫布。所以如果想實現(xiàn)彈幕功能,只要獲取輸入文本框中的文本,再寫到圖片上就好了。cv2.putText能夠?qū)崿F(xiàn)這個功能,但無法添加中文,所以我們需要換一種方法。

首先,我們需要from PIL import ImageDraw,ImageFont

然后用ImageDraw.Draw轉(zhuǎn)換圖片格式,轉(zhuǎn)換后就可以調(diào)用.text()往圖片上寫中文了。

具體實現(xiàn)過程,只需要修改前文的一個函數(shù):

def tkImage(n):

global nowt,pointx,txt

#倍速在這里實現(xiàn)

for i in range(n):

ref,frame = vc1.read()

pilImage = Image.fromarray(frame)

draw = ImageDraw.Draw(pilImage)

font = ImageFont.truetype("simhei.ttf", 40, encoding="utf-8") #參數(shù)1:字體文件路徑,參數(shù)2:字體大小

#txt是讀取的Entry內(nèi)容,在button關(guān)聯(lián)的函數(shù)中獲取

if txt!="":

draw.text((pointx, pointy), txt, (255, 255, 255), font=font) #pointx, pointy是文字添加的位置

pointx-=10 #每次向左移動10個單位

if(pointx==0):

pointx=size[1]

txt=""

pilImage = cv2.cvtColor(np.array(pilImage), cv2.COLOR_BGR2RGB)

pilImage = Image.fromarray(pilImage)

pilImage = pilImage.resize((window_width, window_height),Image.ANTIALIAS)

tkImage = ImageTk.PhotoImage(image=pilImage)

nowt+=n #記錄當前的幀數(shù)

return tkImage

現(xiàn)在我們把前文的顯示四張圖像改成一張,重新整理一下代碼:

import time

import tkinter as tk

from tkinter import *

from tkinter import ttk

import cv2

from PIL import Image, ImageTk,ImageFilter,ImageDraw,ImageFont

import multiprocessing

import numpy as np

import random

import os

filePath = 'D:\\movie\\' #電影存放路徑

mlist=os.listdir(filePath) #文件夾下所有文件名稱

window_width=960 #界面寬

window_height=760 #界面長

image_width=int(window_width*0.5) #圖像寬

image_height=int(window_height*0.5) #圖像長

imagepos_x=0 #畫布位置x

imagepos_y=0 #畫布位置Y

lock=0 #暫停標志

n=1 #初始倍速

nowt=0 #當前幀數(shù)

nows=0 #當前播放時長(秒)

pointx=0 #彈幕起始點橫坐標

pointy=0 #彈幕起始點縱坐標

txt="" #彈幕內(nèi)容

#獲取當前圖像

def tkImage(n):

#倍速在這里實現(xiàn)

global nowt,pointx,pointy,txt

for i in range(n):

ref,frame = vc1.read()

pilImage = Image.fromarray(frame)

draw = ImageDraw.Draw(pilImage)

font = ImageFont.truetype("simhei.ttf", 40, encoding="utf-8")#參數(shù)1:字體文件路徑,參數(shù)2:字體大小

if txt!="":

draw.text((pointx, pointy), txt, (255, 255, 255), font=font)

pointx-=10

if(pointx==-50):

pointx=size[1]

txt=""

pilImage = cv2.cvtColor(np.array(pilImage), cv2.COLOR_BGR2RGB)

pilImage = Image.fromarray(pilImage)

pilImage = pilImage.resize((window_width, 720),Image.ANTIALIAS)

tkImage1 = ImageTk.PhotoImage(image=pilImage)

nowt+=n

return tkImage1

#圖像的顯示與更新

def video():

global nows,nowt

def video_loop():

global nows,nowt

try:

while True:

if lock % 2 == 0: #是否暫停

picture1=tkImage(n)

if nowt >= fps:

nowt=0 #每過一秒則清零重計

nows+=1 #每過一秒,當前播放時間也加1

mi=str(int(nows/60)) #分鐘

se=str(int(nows%60)) #秒

if int(mi)<10:

mi="0"+mi

if int(se)<10:

se="0"+se

showt=mi+":"+se #當前時間

show=showt+"/"+totalt #最終顯示格式(當前時間/總時長)

tlabel.config(text=show)

canvas.coords(fill_line, (0, 0, int(window_width/tt*nows), 15)) #填充進度條

canvas1.create_image(0,0,anchor='nw',image=picture1)

win.update_idletasks()

win.update()

else:

win.update_idletasks()

win.update()

except:

return

#每次開始播放前初始化

nows,nowt=0,0

canvas.coords(fill_line, (0, 0, 0, 15))

video_loop()

vc1.release()

cv2.destroyAllWindows()

#右鍵事件:倍速

def right(self):

global n

n+=1

if n>4:

n=1

#左鍵事件:暫停

def left(self):

global lock

lock+=1

#按鈕事件:獲取彈幕

def get_txt():

global txt,pointx,pointy

txt=E1.get()

pointx=size[1] #初始x坐標

pointy=random.randint(50,150) #初始y坐標隨機

E1.delete(0, END)

#播放選中文件

def start():

global vc1,size,frames_num,fps,totalt,tt,pointx

val = theLB.get() #獲得下拉框當前內(nèi)容

vc1 = cv2.VideoCapture(filePath+val) #讀取視頻

size = (int(vc1.get(cv2.CAP_PROP_FRAME_HEIGHT)), int(vc1.get(cv2.CAP_PROP_FRAME_WIDTH))) #視頻圖像的長和寬

frames_num=vc1.get(cv2.CAP_PROP_FRAME_COUNT) #總幀數(shù)

fps = vc1.get(cv2.CAP_PROP_FPS) #幀率

totalt=str(int(frames_num/fps/60))+":"+str(int(frames_num/fps)%60) #視頻時長

tt=int(frames_num/fps) #進度條疊滿所需次數(shù)

pointx=size[1] #彈幕起始坐標x

video()

#跳轉(zhuǎn)到指定位置

def kj():

global nows,vc1

time=int(int(s1.get())*frames_num/fps/100) #要跳轉(zhuǎn)到的時長

vc1.set(cv2.CAP_PROP_POS_FRAMES,int(time*fps)) #讀取到指定幀數(shù)

ref,frame = vc1.read()

nows=time

'''布局'''

win = tk.Tk()

win.geometry(str(window_width+120)+'x'+str(window_height+20))

#顯示視頻的畫布

canvas1 =Canvas(win,bg='white',width=window_width,height=720)

canvas1.place(x=imagepos_x,y=imagepos_y)

canvas1.bind('', left)

canvas1.bind('', right)

#顯示進度條的畫布

canvas = Canvas(win, width=image_width*2, height=15, bg="white")

canvas.place(x=0, y=722)

fill_line=canvas.create_rectangle(0,0,0,15,fill = 'LightGreen') #坐標是相對于畫布的

#彈幕輸入框

E1 = Entry(win, bd =5,width=100)

E1.place(x=0, y=745)

#發(fā)送彈幕按鈕

B1 = Button(win, text="發(fā)送", command=get_txt,font=('黑體', 10),fg='blue',width=10,height=2)

B1.place(x=750, y=742)

#顯示時間的Label

tlabel = Label(win,font=('黑體', 13),text='')

tlabel.place(x=850, y=750)

#選擇影片下拉框

theLB = ttk.Combobox(win,width=12,height=10)

theLB["values"] = mlist

theLB.current(0) #默認選第一個

theLB.place(x=965, y=0)

#播放影片按鈕

B2 = Button(win, text="播放", command=start,font=('黑體', 10),fg='red',width=10,height=2)

B2.place(x=980, y=50)

#跳轉(zhuǎn)按鈕

B3 = Button(win, text="跳轉(zhuǎn)", command=kj,font=('黑體', 10),fg='red',width=10,height=2)

B3.place(x=980, y=150)

#選擇跳轉(zhuǎn)位置的滾動條

s1 = Scale(win,from_=0,to=99,orient=HORIZONTAL) #orient=HORIZONTAL設置水平方向顯示

s1.place(x=970, y=100)

win.mainloop()

上述代碼不僅實現(xiàn)了我們所說的功能,我還用下拉框Combobox自動加載文件夾下的所有文件名,以供選擇文件播放;并且能夠拖動滾動條跳轉(zhuǎn)到指定位置,利用了cv2.VideoCapture的.set()方法。

怎么樣,更像一個視頻播放器了吧?如果你還想往下做,可以加入“添加到播放列表”的功能,選擇其他路徑下的文件添加到全局變量mlist里,然后更新一下Combobox的values即可。

來看看我們的成果吧:https://www.zhihu.com/video/1240349393213698048

費了半天勁,反正還是只能看默劇。。

總結(jié)

以上是生活随笔為你收集整理的python在tk界面播放本地视频_tkinter做一个本地视频播放器(2)——弹幕的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。