使用 OpenCV 和 PyAudio 同步音频和视频

2024-01-08

我已经让 OpenCV 和 PyAudio 都工作了,但是我不确定如何将它们同步在一起。我无法从 OpenCV 获取帧速率并测量帧时时刻刻变化的调用时间。然而,对于 PyAudio 来说,它的基础是获取一定的采样率。我如何将它们同步到相同的速率。我假设编解码器有一些标准或某种方式来做到这一点。 (我已经尝试过谷歌,我得到的只是有关口型同步的信息:/)。

OpenCV 帧率

from __future__ import division
import time
import math
import cv2, cv

vc = cv2.VideoCapture(0)
# get the frame
while True:

    before_read = time.time()
    rval, frame = vc.read()
    after_read  = time.time()
    if frame is not None:
        print len(frame)
        print math.ceil((1.0 / (after_read - before_read)))
        cv2.imshow("preview", frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    else:
        print "None..."
        cv2.waitKey(1)

# display the frame

while True:
    cv2.imshow("preview", frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

抓取并保存音频

from sys import byteorder
from array import array
from struct import pack

import pyaudio
import wave

THRESHOLD = 500
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 44100

def is_silent(snd_data):
    "Returns 'True' if below the 'silent' threshold"
    print "\n\n\n\n\n\n\n\n"
    print max(snd_data)
    print "\n\n\n\n\n\n\n\n"
    return max(snd_data) < THRESHOLD

def normalize(snd_data):
    "Average the volume out"
    MAXIMUM = 16384
    times = float(MAXIMUM)/max(abs(i) for i in snd_data)

    r = array('h')
    for i in snd_data:
        r.append(int(i*times))
    return r

def trim(snd_data):
    "Trim the blank spots at the start and end"
    def _trim(snd_data):
        snd_started = False
        r = array('h')

        for i in snd_data:
            if not snd_started and abs(i)>THRESHOLD:
                snd_started = True
                r.append(i)

            elif snd_started:
                r.append(i)
        return r

    # Trim to the left
    snd_data = _trim(snd_data)

    # Trim to the right
    snd_data.reverse()
    snd_data = _trim(snd_data)
    snd_data.reverse()
    return snd_data

def add_silence(snd_data, seconds):
    "Add silence to the start and end of 'snd_data' of length 'seconds' (float)"
    r = array('h', [0 for i in xrange(int(seconds*RATE))])
    r.extend(snd_data)
    r.extend([0 for i in xrange(int(seconds*RATE))])
    return r

def record():
    """
    Record a word or words from the microphone and 
    return the data as an array of signed shorts.

    Normalizes the audio, trims silence from the 
    start and end, and pads with 0.5 seconds of 
    blank sound to make sure VLC et al can play 
    it without getting chopped off.
    """
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT, channels=1, rate=RATE,
        input=True, output=True,
        frames_per_buffer=CHUNK_SIZE)

    num_silent = 0
    snd_started = False

    r = array('h')

    while 1:
        # little endian, signed short
        snd_data = array('h', stream.read(1024))
        if byteorder == 'big':
            snd_data.byteswap()

        print "\n\n\n\n\n\n"
        print len(snd_data)
        print snd_data

        r.extend(snd_data)

        silent = is_silent(snd_data)

        if silent and snd_started:
            num_silent += 1
        elif not silent and not snd_started:
            snd_started = True

        if snd_started and num_silent > 1:
            break

    sample_width = p.get_sample_size(FORMAT)
    stream.stop_stream()
    stream.close()
    p.terminate()

    r = normalize(r)
    r = trim(r)
    r = add_silence(r, 0.5)
    return sample_width, r

def record_to_file(path):
    "Records from the microphone and outputs the resulting data to 'path'"
    sample_width, data = record()
    data = pack('<' + ('h'*len(data)), *data)

    wf = wave.open(path, 'wb')
    wf.setnchannels(1)
    wf.setsampwidth(sample_width)
    wf.setframerate(RATE)
    wf.writeframes(data)
    wf.close()

if __name__ == '__main__':
    print("please speak a word into the microphone")
    record_to_file('demo.wav')
    print("done - result written to demo.wav")

我认为你最好使用 GSreamer 或 ffmpeg,或者如果你使用的是 Windows,则使用 DirectShow。这些库可以处理音频和视频,并且应该有某种多路复用器来允许您正确混合视频和音频。

但如果你真的想使用 Opencv 来做到这一点,你应该能够使用VideoCapture要获得帧速率,您是否尝试过使用this http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture-get?

fps = cv.GetCaptureProperty(vc, CV_CAP_PROP_FPS)

另一种方法是将帧数除以持续时间来估计 fps:

nFrames  = cv.GetCaptureProperty(vc, CV_CAP_PROP_FRAME_COUNT)
           cv.SetCaptureProperty(vc, CV_CAP_PROP_POS_AVI_RATIO, 1)
duration = cv.GetCaptureProperty(vc, CV_CAP_PROP_POS_MSEC)
fps = 1000 * nFrames / duration;

我不确定我是否理解您在这里尝试做什么:

before_read = time.time()
rval, frame = vc.read()
after_read  = time.time()

在我看来,做after_read - before_read仅测量 OpenCV 加载下一帧所需的时间,不测量 fps。 OpenCV 并不尝试进行播放,它只是加载帧,并且它会尝试以最快的速度执行此操作,我认为没有办法对其进行配置。我认为放一个waitKey(1/fps)显示每一帧后将实现您正在寻找的内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 OpenCV 和 PyAudio 同步音频和视频 的相关文章

随机推荐

  • 节是柯里化的结果吗?

    Hutton 的 Haskell 编程 一般来说 如果 是一个运算符 那么表达式的形式 x 和 y 用于论证x and y称为节 其作为函数的含义可以是 使用 lambda 表达式形式化如下 x gt y gt x y x y gt x y
  • Restlet流数据

    我正在执行一项任务 我将从设备读取数据并使其通过网络服务可用 每秒读取数据 4 次 我希望 Web 客户端具有开放的 HTTP 连接 并使用以下方式将设备读数作为流获取分块传输 http en wikipedia org wiki Chun
  • VSX?虚拟MX?阿尔蒂维克?虚拟现实?振动时效?!这些 PowerPC SIMD 缩写词之间有何关系?

    我听说过很多关于 Altivec 寄存器的事 但我什至没有在网上找到它POWER9 指令集架构 https www docdroid net tWT7hjD powerisa v30 pdf 在该文档中 我只在第 6 章 矢量设施 和第 7
  • 如何获取 Android 11 中已安装应用的列表

    开发者网站上描述了这一行 但我没有完全理解它 Call getInstalledApplications or getInstalledPackages Both methods should return a filtered list
  • Python 压缩子文件夹而不是整个文件夹路径

    我有一个程序可以将所有内容压缩到一个文件夹中 我没有编写这段代码 但我在网上找到了它并且我正在使用它 我打算压缩一个文件夹 例如 C folder1 folder2 folder3 我想将folder3 及其所有内容压缩到一个文件中 例如f
  • 如何列出从单个卷 ID EC2 实例创建的所有快照?

    在过去的几个月中 我们的快照备份量增加 因此我们每月在亚马逊 EC2 上的账单也随之增加 现在我想删除一些旧的 EC2 快照 所以问题是 如何使用 EC2 命令行工具查找从单个卷 ID 创建的所有快照 I tried ec2 describ
  • 访问另一个类的 Swing 组件

    我有两节课gameWindow and gameEngine 主要方法是在gameWindowclass so 是 swing GUI 代码 现在 我想访问中的 swing 组件gameEngine 怎么做 我总是得到cannot find
  • std::bit_cast 和 std::start_lifetime_as 之间有什么有用的区别吗?

    std bit cast显然是在 c 20 中引入的 和std start lifetime as被提议用于 c 23 来自P0593R5 https wg21 link p0593R5 由于它们似乎都要求所涉及的数据类型无论如何都是微不足
  • 如何在Flutter中复用非Widget类?

    我知道我们应该使用组合优于继承 https stackoverflow com a 51477727 1769177在颤振中 当我们谈论时这很有效Widgets 但是当一个类不是一个类时我该怎么办Widget 例如 我想要我的TextFie
  • 如何在代码隐藏中将 FrameworkElement.Width 属性设置为 QualifiedDouble 的值?

    我试图将我的一个控件的宽度属性设置为qualifiedDouble 如 MSDN 上所述 http msdn microsoft com en us library system windows frameworkelement width
  • Keras Embedding 层中的 mask_zero 如何工作?

    我想mask zero True当输入值为 0 时将输出 0 因此后续层可以跳过计算或其他操作 如何mask zero works 例子 data in np array 1 2 0 0 data in shape gt gt gt 1 4
  • 根据语言更改文本

    我正在使用带有语言切换器的 Wordpress 在各种语言之间进行切换 在模板中 我使用这段代码来切换硬编码文本 This is english This is another language 我有一个侧边栏 但它是通过各种小部件创建的
  • 使用 io.TextIOWrapper 包装打开的流

    如何包装一个开放的二进制流 Python 2file Python 3io BufferedReader an io BytesIO 在一个io TextIOWrapper 我正在尝试编写不改变即可工作的代码 在 Python 2 上运行
  • Xcode 6 和 Swift 中视图之间类似 Snapchat 的滑动导航)

    我一直在尝试使用滑动手势识别器和嵌入式导航控制器在我的应用程序中的视图控制器之间实现滑动导航 但它看起来与 Snapchat 的导航并不接近 实现搜索功能最有效 最合适的方法是什么 我确实是 Swift 和编程的新手 我会很感激每一个有用的
  • 找不到模块错误:没有名为“chart_studio”的模块

    I run pip install chart studio在 jupyter 笔记本中 然后运行这段代码时 import numpy as np import pandas as pd import cufflinks as cf imp
  • 如何用JQ补数字?

    我想向数字中的字符串添加前导 尾随零 结果字符串需要包含 01 或 001 而不是 1 我注意到项目https github com joelpurra jq zeros但我从包管理器 dnf fedora 安装了 jq 所以需要一些jqn
  • 绑定复选框列表

    我需要一种简单的方法来绑定复选框列表asp net C 我从数据库 Id Name 和 IsActive 中提取 3 列 Id 和 Name 我想通过它的名字就可以清楚地看出 IsActive 将用于显示选中和未选中的框 我只是想知道 数据
  • 在 Angular 2 中从子组件更新父组件属性

    我在用着 input从父组件接收属性 以便激活子组件元素之一中的 CSS 类 我能够从父母那里接收财产并激活班级 但这只有效一次 我从父级接收的属性是一个布尔数据类型 当我将其状态设置为false从子组件开始 它在父组件中不会改变 Plun
  • webpack 4 给出背景: url([object Module]) 作为背景图像

    我在设置 web pack 4 和 svg sprite loader 将 svg 图标渲染为背景图像时遇到问题 我遵循 svg sprite loader 官方文档中的这些说明 https github com kisenka svg s
  • 使用 OpenCV 和 PyAudio 同步音频和视频

    我已经让 OpenCV 和 PyAudio 都工作了 但是我不确定如何将它们同步在一起 我无法从 OpenCV 获取帧速率并测量帧时时刻刻变化的调用时间 然而 对于 PyAudio 来说 它的基础是获取一定的采样率 我如何将它们同步到相同的