微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 OpenCV 和 ffpyplayer 实现音视频同步

如何解决使用 OpenCV 和 ffpyplayer 实现音视频同步

我目前正在开发一个“游戏”,允许用户在观看视频时移动圆圈的位置。视频显示了两个人,每个人轮流发言。用户的任务是更改当前发言者看到的圆圈的位置。发生这种情况时,我计划在某个时候更改视频,而用户不会注意到“游戏”和圆圈继续显示

为了达到这个目的,我写了下面的代码。该代码接受用户的输入,并将所有数据发送到 TCP 服务器并将信息打印到记录器文件中。但我遇到了一个问题。首先,音频和视频不同步,即使使用waitkey(1)的最低值,音频也比视频快

任何有关如何解决此问题的帮助将不胜感激。提前致谢。

PS- 我使用的是 Visual Studio 代码,我的 Python 版本是 3.9.6 64 位。

import cv2 as cv #import the OpenCV library
import numpy as np #Import Numpy Library
import socket  # socket creation for Telnet
from datetime import datetime
from telnetlib import Telnet #telnet client
from ffpyplayer.player import MediaPlayer #ffpyplayer for playing audio

current_date_time = datetime.Now().strftime('%Y-%m-%d-%H:%M:%s')
HOST = '127.0.0.1'  # The remote host
PORT = 4212  # The same port as used by the server
TCP_PORT = 9999  # port used to connect with the server file

def send_data(message,s,output):
    s.sendall(message.encode())
    data = s.recv(1024)
    output.write('\n'+ current_date_time+' '+message+ '\n')
    return data

def circle(frame,left):
    if left:
        cv.circle(frame,(450,250),20,(255,255,255),50)
    if not left:
        cv.circle(frame,(1400,50)

def video():
    cap1 = cv.VideoCapture('P1.mp4') # the video that we want
    player = MediaPlayer('P1.mp4')
    circle_is_left = True
    if (cap1.isOpened()== False):
        print("Error opening video 1")  
    while (cap1.isOpened()):
        ret,frame = cap1.read() #capture frame-by-frame video
        audio_frame,val=player.get_frame() # capture frame-by-frame audio
        if ret== True:
            key_pressed = cv.waitKey(1)
            if key_pressed == ord(' '): #pressing space bar ends the video
                with open('out.txt','a') as output:
                    send_data('video 1 is changed',output)
                break
            elif key_pressed == 2: #left key pressed changes circle to lett
                circle_is_left = True
                with open('out.txt','a') as output:
                    send_data('left',output)
            elif key_pressed == 3: # right key pressed changes circle to right
                circle_is_left = False
                with open('out.txt','a') as output:
                    send_data('Right ',output)
            circle(frame,circle_is_left) #display the circle at all times
            cv.imshow('cap1',frame) #display resulting frame 
            if val != 'eof' and audio_frame is not None:
                img,t = audio_frame
    cap1.release()
    cv.destroyAllWindows()
 
    cap2 = cv.VideoCapture('P2.mov') # the video that we want
    player2 = MediaPlayer('P2.mov')
    circle_is_left = True
    if (cap2.isOpened()== False):
        print("Error opening video 2")  
    while (cap2.isOpened()):
        ret,frame = cap2.read() #capture frame-by-frame video
        audio_frame,val=player2.get_frame() # capture frame-by-frame audio
        if ret== True:
            key_pressed = cv.waitKey(1)
            if key_pressed == ord(' '): #pressing space bar ends the video
                with open('out.txt',circle_is_left) #display the circle at all times
            cv.imshow('cap2',t = audio_frame
    cap2.release()
    cv.destroyAllWindows()

def main():
    print("Game1.py is connected to TCP server")
    video()
    
if __name__=='__main__':
    s = socket.socket(socket.AF_INET,socket.soCK_STREAM)
    s.connect((HOST,TCP_PORT))
    main()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。