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 相关文章推荐
windows及linux环境下永久修改pip镜像源的方法
Nov 28 Python
对numpy中的where方法嵌套使用详解
Oct 31 Python
用django-allauth实现第三方登录的示例代码
Jun 24 Python
Python 多个图同时在不同窗口显示的实现方法
Jul 07 Python
Python Django Vue 项目创建过程详解
Jul 29 Python
解决在pycharm运行代码,调用CMD窗口的命令运行显示乱码问题
Aug 23 Python
OpenCV Python实现图像指定区域裁剪
Mar 12 Python
Python爬虫Scrapy框架CrawlSpider原理及使用案例
Nov 20 Python
python 实现超级玛丽游戏
Nov 25 Python
python进行二次方程式计算的实例讲解
Dec 06 Python
matplotlib 范围选区(SpanSelector)的使用
Feb 24 Python
python中Pexpect的工作流程实例讲解
Mar 02 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
ThinkPHP模板范围判断输出In标签与Range标签用法详解
2014/06/30 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
PHP多维数组转一维数组的简单实现方法
2015/12/23 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
2017/05/29 PHP
用 JSON 处理缓存
2007/04/27 Javascript
js点击页面其它地方将某个显示的DIV隐藏
2012/07/12 Javascript
js的2种继承方式详解
2014/03/04 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
javascript if条件判断方法小结
2014/05/17 Javascript
Javascript基础教程之for循环
2015/01/18 Javascript
简介JavaScript中的getSeconds()方法的使用
2015/06/10 Javascript
jQuery平滑旋转幻灯片特效代码分享
2015/09/07 Javascript
jQueryUI 拖放排序遇到滚动条时有可能无法执行排序的小bug及解决方案
2016/12/19 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
2017/07/03 Javascript
JS数组进阶示例【数组的几种函数用法】
2020/01/16 Javascript
《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
2020/04/08 Javascript
Auto.JS实现抖音刷宝等刷视频app,自动点赞,自动滑屏,自动切换视频功能
2020/05/08 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
Openlayers实现图形绘制
2020/09/28 Javascript
[15:23]教你分分钟做大人:虚空假面
2014/10/30 DOTA
[01:19]DOTA2城市挑战赛报名开始 开启你的城市传奇
2018/03/23 DOTA
[46:37]LGD vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python利用lxml读写xml格式的文件
2017/08/10 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
python爬虫获取新浪新闻教学
2018/12/23 Python
python版DDOS攻击脚本
2019/06/12 Python
Python如何访问字符串中的值
2020/02/09 Python
pytorch中的inference使用实例
2020/02/20 Python
阿里旅行:飞猪
2017/01/05 全球购物
玲玲的画教学反思
2014/02/04 职场文书
大学生两会精神学习心得体会
2014/03/10 职场文书
党员干部公开承诺书
2014/03/26 职场文书
毕业生实习证明
2014/09/19 职场文书
李白故里导游词
2015/02/12 职场文书
2015年档案管理工作总结
2015/04/08 职场文书
Nginx限流和黑名单配置
2022/05/20 Servers