python录制音频和视频(opencv、pyaudio);解决opencv录制的视频播放速度快的问题
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv
免费下载资源
·
录制视频和音频并合并
import pyaudio
import cv2
import subprocess
import wave
from platform import release
# Set up PyAudio
p = pyaudio.PyAudio()
# Set up OpenCV
cap = cv2.VideoCapture(0)
# 音频采样率
sample_rate = 16000
# fps
frame_rate = 15.625
# 打开pyaudio流录制音频
audio_stream = p.open(format=pyaudio.paInt16,
channels=1,
rate=sample_rate,
frames_per_buffer=1024,
input=True)
# 设置视频的FourCC代码和帧大小
fourcc = cv2.VideoWriter_fourcc(*'XVID')
frame_size = (640, 480)
# 创建一个VideoWriter对象来保存视频
video_writer = cv2.VideoWriter('b.mp4', fourcc, frame_rate, frame_size)
audio_data = []
# 开始循环录制
while True:
# 显示摄像头
ret, frame = cap.read()
if ret:
# 将视频帧保存到视频文件
video_writer.write(frame)
cv2.imshow('Camera', frame)
# 从麦克风读取音频数据并将其附加到audio_data变量
audio = audio_stream.read(1024)
audio_data.append(audio)
# 如果用户按下'q'键,则打破循环
if cv2.waitKey(1) & 0xFF == ord('q'):
cap.release()
# 释放摄像头资源
video_writer.release()
# 关闭录像窗口
cv2.destroyAllWindows()
# 释放音频资源
audio_stream.stop_stream()
audio_stream.close()
p.terminate()
break
else:
break
# 保存音频文件为wav
wf = wave.open('a.wav', 'wb')
wf.setnchannels(1)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(16000)
wf.writeframes(b''.join(audio_data))
wf.close()
# 合并音频和视频文件
subprocess.run(["ffmpeg", "-i", "b.mp4", "-i", "a.wav", "-c:v", "copy", "-c:a", "aac", "-strict", "experimental", "output.mp4"])
这里需要注意,录制生成的a.wav
、b.mp4
和最终的output.mp4
生成之后,下次运行代码之前要将它们删掉,不然程序一直会处在运行状态。(当然可以在文件名不覆盖的情况下不删除)
opencv录制视频播放速度过快(帧率)
参考👉opencv录屏
虽然这一篇写的是录屏,但博主说的调整帧率的方法还是挺好使的。
new_fps = old_fps * (int(Count) / old_fps) / screen_time
我首先使用录制代码录制了一份frame_rate = 24
的视频,播放起来速度还是很快,而且合并上音频音画并不同步。
获取视频文件帧率、帧数和持续时间
采取上面链接博主的方法,我首先获取frame_rate = 24
的视频的帧率和帧数
import cv2
# Open the video file
video = cv2.VideoCapture("b.mp4")
# Get the frame rate and number of frames
frame_rate = video.get(cv2.CAP_PROP_FPS)
frame_count = video.get(cv2.CAP_PROP_FRAME_COUNT)
# Calculate the duration of the video
duration = frame_count / frame_rate
# Print the frame rate, number of frames, and duration
print("Frame rate:", frame_rate)
print("Number of frames:", frame_count)
print("Duration:", duration)
# Release the video file
video.release()
输出:
Frame rate: 24.0
Number of frames: 80.0
Duration: 3.3333333333333335
因为音频录制的时间没有什么问题,速度也没啥问题,所以我采用音频的持续时间作为整段视频原本应该持续的时间
获取音频文件持续时间
# 获取音频时长
def audio_duration(audio_file):
import wave
with wave.open(audio_file, 'rb') as wav_file:
num_frames = wav_file.getnframes()
frame_rate = wav_file.getframerate()
duration = num_frames / frame_rate
return duration
audio_duration('a.wav')
输出:
5.12
在看之前博主给出的公式 new_fps = old_fps * (int(Count) / old_fps) / screen_time
那么我这里就是new_fps = 24*(80/24)/5.12=15.625
所以,我将录制的代码中frame_rate
改为了15.625,最终合成的视频发现音像是同步的。单独生成的音频和视频也会做后续的分析。如果不需要,可以不留着这两个文件,remove即可。
我的邮箱:k1933211129@163.com,CSDN私信很少看,欢迎各位大佬不吝赐教~
GitHub 加速计划 / opencv31 / opencv
148
15
下载
OpenCV: 开源计算机视觉库
最近提交(Master分支:4 个月前 )
96d6395a
Add include chrono gstreamersource.cpp 2 天前
fe649f4a - 2 天前
更多推荐
已为社区贡献1条内容
所有评论(0)