Python+opencv+pyaudio实现带声音屏幕录制


Posted in Python onDecember 23, 2019

基于个人的爱好和现实的需求,决定用Python做一个屏幕录制的脚本。因为要看一些加密的视频,每次都要登录,特别麻烦,遂决定用自己写的脚本,将加密视频的播放过程全程录制下来,这样以后看自己的录播就好了。结合近期自己学习的内容,正好用Python来练练手,巩固自己的学习效果。

经过多番搜索,决定采用Python+opencv+pyaudio来实现屏幕录制。网上搜索到的录屏,基本都是不带声音的,而我要实现的是带声音的屏幕录制。下面就开始一步一步的实现吧。

声音录制

import pyaudio
import wave
import sys

CHUNK = 1024
if len(sys.argv) < 2:
 print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])
 sys.exit(-1)

wf = wave.open(sys.argv[1], 'rb')
p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
    channels=wf.getnchannels(),
    rate=wf.getframerate(),
    output=True)

data = wf.readframes(CHUNK)
while data != '':
 stream.write(data)
 data = wf.readframes(CHUNK)

stream.stop_stream()
stream.close()
p.terminate()

简洁回调函数版音频录制

import pyaudio
import wave
import time
import sys

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 10
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)

time_count = 0
def callback(in_data, frame_count, time_info, status):
 wf.writeframes(in_data)
 if(time_count < 10):
  return (in_data, pyaudio.paContinue)
 else:
  return (in_data, pyaudio.paComplete)

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
    channels=wf.getnchannels(),
    rate=wf.getframerate(),
    input=True,
    stream_callback=callback)

stream.start_stream()
print("* recording")
while stream.is_active():
 time.sleep(1)
 time_count += 1

stream.stop_stream()
stream.close()
wf.close()
p.terminate()
print("* recording done!")

视频录制(无声音)

from PIL import ImageGrab
import numpy as np
import cv2

image = ImageGrab.grab()#获得当前屏幕
width = image.size[0]
height = image.size[1]
print("width:", width, "height:", height)
print("image mode:",image.mode)
k=np.zeros((width,height),np.uint8)
fourcc = cv2.VideoWriter_fourcc(*'XVID')#编码格式
video = cv2.VideoWriter('test.avi', fourcc, 25, (width, height))
#输出文件命名为test.mp4,帧率为16,可以自己设置
while True:
 img_rgb = ImageGrab.grab()
 img_bgr=cv2.cvtColor(np.array(img_rgb), cv2.COLOR_RGB2BGR)#转为opencv的BGR格式
 video.write(img_bgr)
 cv2.imshow('imm', img_bgr)
 if cv2.waitKey(1) & 0xFF == ord('q'):
  break
video.release()
cv2.destroyAllWindows()

录制的音频与视频合成为带声音的视频

录制200帧,带音频的MP4视频,单线程

import wave
from pyaudio import PyAudio,paInt16
from PIL import ImageGrab
import numpy as np
import cv2
from moviepy.editor import *
from moviepy.audio.fx import all
import time

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
WAVE_OUTPUT_FILENAME = "output.wav"

p = pyaudio.PyAudio()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
audio_record_flag = True
def callback(in_data, frame_count, time_info, status):
 wf.writeframes(in_data)
 if audio_record_flag:
  return (in_data, pyaudio.paContinue)
 else:
  return (in_data, pyaudio.paComplete)
stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
    channels=wf.getnchannels(),
    rate=wf.getframerate(),
    input=True,
    stream_callback=callback)
image = ImageGrab.grab()#获得当前屏幕
width = image.size[0]
height = image.size[1]
print("width:", width, "height:", height)
print("image mode:",image.mode)
k=np.zeros((width,height),np.uint8)

fourcc = cv2.VideoWriter_fourcc(*'XVID')#编码格式
video = cv2.VideoWriter('test.mp4', fourcc, 9.5, (width, height))
#经实际测试,单线程下最高帧率为10帧/秒,且会变动,因此选择9.5帧/秒
#若设置帧率与实际帧率不一致,会导致视频时间与音频时间不一致

print("video recording!!!!!")
stream.start_stream()
print("audio recording!!!!!")
record_count = 0
while True:
 img_rgb = ImageGrab.grab()
 img_bgr=cv2.cvtColor(np.array(img_rgb), cv2.COLOR_RGB2BGR)#转为opencv的BGR格式
 video.write(img_bgr)
 record_count += 1
 if(record_count > 200):
  break
 print(record_count, time.time())

audio_record_flag = False
while stream.is_active():
 time.sleep(1)

stream.stop_stream()
stream.close()
wf.close()
p.terminate()
print("audio recording done!!!!!")

video.release()
cv2.destroyAllWindows()
print("video recording done!!!!!")

print("video audio merge!!!!!")
audioclip = AudioFileClip("output.wav")
videoclip = VideoFileClip("test.mp4")
videoclip2 = videoclip.set_audio(audioclip)
video = CompositeVideoClip([videoclip2])
video.write_videofile("test2.mp4",codec='mpeg4')

看来要提高帧率必须使用队列加多线程了,这一步等到以后来添加吧。不过总是觉得用OpenCV来实现视频录制,有点怪异,毕竟opencv是用来做图像与视频分析的,还是走正道认真捣鼓opencv该做的事情吧。

以上这篇Python+opencv+pyaudio实现带声音屏幕录制就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python创建只读属性对象的方法(ReadOnlyObject)
Feb 10 Python
python计算程序开始到程序结束的运行时间和程序运行的CPU时间
Nov 28 Python
Python FTP操作类代码分享
May 13 Python
python处理文本文件实现生成指定格式文件的方法
Jul 31 Python
Python编程scoketServer实现多线程同步实例代码
Jan 29 Python
基于Python实现的微信好友数据分析
Feb 26 Python
Python装饰器知识点补充
May 28 Python
Django使用Channels实现WebSocket的方法
Jul 28 Python
Win10系统下安装labelme及json文件批量转化方法
Jul 30 Python
tensorflow tf.train.batch之数据批量读取方式
Jan 20 Python
Python正则表达式学习小例子
Mar 03 Python
Python中格式化字符串的四种实现
May 26 Python
python 实现屏幕录制示例
Dec 23 #Python
关于ZeroMQ 三种模式python3实现方式
Dec 23 #Python
Python 内置函数globals()和locals()对比详解
Dec 23 #Python
Python 项目转化为so文件实例
Dec 23 #Python
python 解决cv2绘制中文乱码问题
Dec 23 #Python
python 实现查询Neo4j多节点的多层关系
Dec 23 #Python
python 多进程队列数据处理详解
Dec 23 #Python
You might like
php数据库抽象层 PDO
2011/05/07 PHP
PHP使用Pear发送邮件(Windows环境)
2016/01/05 PHP
php中array_unshift()修改数组key注意事项分析
2016/05/16 PHP
php flush无效,IIS7下php实时输出的方法
2016/08/25 PHP
Yii 2.0如何使用页面缓存方法示例
2017/05/23 PHP
PHP SESSION机制的理解与实例
2019/03/22 PHP
初窥JQuery(一)jquery选择符 必备知识点
2010/11/25 Javascript
js如何获取file控件的完整路径具体实现代码
2013/05/15 Javascript
jquery实现checkbox 全选/全不选的通用写法
2014/02/22 Javascript
javascript进行数组追加方法小结
2014/06/16 Javascript
正则表达式替换html元素属性的方法
2016/11/26 Javascript
JavaScript实现星级评分
2017/01/12 Javascript
vue.js数据绑定的方法(单向、双向和一次性绑定)
2017/07/13 Javascript
vue双花括号的使用方法 附练习题
2017/11/07 Javascript
在vue中通过axios异步使用echarts的方法
2018/01/13 Javascript
为什么说JavaScript预解释是一种毫无节操的机制详析
2018/11/18 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
javascript+Canvas实现画板功能
2020/06/23 Javascript
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
2020/07/21 Javascript
vue 监听窗口变化对页面部分元素重新渲染操作
2020/07/28 Javascript
安装Python和pygame及相应的环境变量配置(图文教程)
2017/06/04 Python
在python中只选取列表中某一纵列的方法
2018/11/28 Python
python列表list保留顺序去重的实例
2018/12/14 Python
python自动生成证件号的方法示例
2021/01/14 Python
Python Selenium操作Cookie的实例方法
2021/02/28 Python
HTML5 FormData 方法介绍以及实现文件上传示例
2017/09/12 HTML / CSS
laravel使用redis队列实例讲解
2021/03/23 PHP
毕业生的自我评价
2013/12/30 职场文书
学习委员自我鉴定
2014/01/13 职场文书
幼儿园教师工作制度
2014/01/22 职场文书
挂职个人工作总结
2015/03/05 职场文书
小学生读书笔记
2015/07/01 职场文书
外出听课学习心得体会
2016/01/15 职场文书
详解MongoDB的条件查询和排序
2021/06/23 MongoDB
基于Redis6.2.6版本部署Redis Cluster集群的问题
2022/04/01 Redis
Docker部署Mysql8的实现步骤
2022/07/07 Servers