当前位置: 首页 > 编程日记 > 正文

采集音频和摄像头视频并实时H264编码及AAC编码

0. 前言

我在前两篇文章中写了DirectShow捕获音视频然后生成avi,再进行264编码的方法。那种方法有一些局限性,不适合实时性质的应用,如:视频会议、视频聊天、视频监控等。本文所使用的技术,适用于这种实时性的应用,通过处理采集出来的音视频的每一帧,实现实时编码,实时输出。这是我做直播系列应用的一部分,目前的情况是输入端采用DirectShow技术捕获音视频,然后对视频进行h.264编码,对音频进行aac编码,输出端则是生成文件,接下来还要进一步扩展输入端和输出端,以支持文件、桌面输入,RTSP、RTMP、HTTP等流式协议输出。

1. 简单介绍

首先是捕获,这里采用了DirectShow的方式,对它进行了一定程度的封装,包括音视频。好处是直接使用native api,你可以做想做的任何修改,坏处是,不能跨平台,采集音视频这种应用,linux平台也是需要滴呀。有跨平台的做法,对视频,可以使用OpenCV,对音频,可以使用OpenAL或PortAudio等,这样就行了。

编码可以选择的余地比较大,对视频来讲,有H264, MPEG-4, WebM/VP8, Theora等,音频有Speex, AAC, Ogg/Vorbis等,它们都有相应的开源项目方案,我采用的是x264进行H264编码,libfaac进行aac编码,之后是否更改编码方案,等具体项目需求再说了。这里提一下WebM,Google牵头的项目,完全开放和自由,使用VP8和Vorbis编码,webm(mkv)封装,有多家巨头支持,目的是想要取代当前的H264视频编码,号称比后者更加优秀,我没有测试过实际效果。不过有商业公司牵头就是不一样,各项支持都很全面,有时间了关注一下。

2. 逻辑和流程

基本的思想是实现dshow ISampleGrabberCB接口,通过回调来保存每一个buffer。除了界面线程和dshow自己的线程之外,我们启动了两个线程,AudioEncoderThread和VideoEncoderThread,分别从SampleGrabber中取出数据,调用编码器进行编码,编码后的文件可以直接输出。看图:

程序是用VS2010构建的,看张工程截图:

Base下面的是对系统API的一些简单封装,主要是线程和锁。我这里简单也封装的了一下dshow的捕获过程,包括graph builder的创建,filter的连接等。directshow是出了名的难用,没办法,难用也得用。因为是VS2010,调用的Windows SDK 7.1中的dshow,没有qedit.h这个文件,而它正式定义ISampleGrabberCB的。不急,系统中还是有qedit.dll的,我们要做的就是从Windows SDK 6.0中,把它拷过来,然后在stdafx.h中加入这几行代码,就可以了

1 #pragma include_alias( "dxtrans.h", "qedit.h" )
2 #define __IDxtCompositor_INTERFACE_DEFINED__
3 #define __IDxtAlphaSetter_INTERFACE_DEFINED__
4 #define __IDxtJpeg_INTERFACE_DEFINED__
5 #define __IDxtKey_INTERFACE_DEFINED__
6 #include "qedit.h"

3. 音视频编码

相关文件:

Encoder下就是音视频编码相关的代码。X264Encoder封装了调用x264编码器的操作,FAACEncoder封装了调用libfaac编码器的操作,VideoEncoderThread和AudioEncoderThread负责主要的流程。下面我把关键代码贴出来,大家可以参考一下。

A. 视频编码线程

主要流程是首先初始化x264编码器,然后开始循环调用DSVideoGraph,从SampleGrabber中取出视频帧,调用x264进行编码,流程比较简单,调用的频率就是你想要获取的视频帧率。要注意的一点是,x264进行编码比较耗时,在计算线程Sleep时间时,要把这个过程消耗的时间算上,以免采集的视频帧率错误。

B. 音频编码线程

主要流程和视频编码线程相同,也是初始化FAAC编码器,然后循环调用DSAudioGraph,从SampleGrabber中取出视频帧,调用faac进行编码。和视频不同的是,音频的sample的频率是非常快的,所以几乎要不断的进行采集,但前提是SampleGrabber中捕获到新数据了才行,不然你的程序cpu就100%了,下面代码中IsBufferAvailaber()就是做这个检测的。

调用faac进行编码的时候,有点需要注意,大家特别注意下,不然编码出来的音频会很不正常,搞不好的话会很头疼的。先看下faac.h的相关接口

1 faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, unsigned int numChannels, 2                   unsigned long *inputSamples, unsigned long *maxOutputBytes); 3  4 int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput, 5              unsigned char *outputBuffer, unsigned int bufferSize);

faacEncEncode第三个参数指的是传入的sample的个数,这个值要和调用faacEncOpen返回的inputSamples相等。要做到这点,就要在dshow中设置好buffsize,公式是:

BufferSize = aac_frame_len * channels * wBytesPerSample // aac_frame_len = 1024

4. 程序界面

运行中

捕获完成后生成aac 和 264文件

生成的aac文件用MediaInfo读出来的编码格式

生成的264文件用MediaInfo读出来的编码格式

用mp4box封装一下,把264和aac存放到mp4容器文件中,就可以在播放器中播放了

转载于:https://www.cnblogs.com/zjoch/archive/2013/05/17/3083023.html

相关文章:

【算法练习】校招研发工程师笔试题

请留言,说出你的解题思路和答案。稍后,我会把参考答案发到留言区。不定期整理相关的问题答案分享。 01、下面对于线性表的叙述中,不正确的是()。 (A)线性表采用顺序存储时,必须占用…

Ubuntu安装tomcat

1.从官网中下载apache-tomcat-**.tar.gz文件 2.在本地文件新建一个文件夹(tomcat),在文件夹中解压压缩包, 不需要使用root: tar -zxvf /home/xcx/下载/apache-tomcat-8.5.11.tar.gz 3.进入解压文件中使用命令,将tomcat中的文件全部设置添加读…

mysql 绑定参数_MySQL 使用 Perl 绑定参数和列

SQL 语句通常是动态构建的,用户提供一些输入,并将其内置到语句中。 程序员每次处理用户的输入时都必须谨慎。 它具有一些严重的安全隐患。 动态构建 SQL 语句的推荐方法是使用参数绑定。绑定参数可以防止 SQL 注入程序。 它会自动转义一些特殊字符并允许…

java入门(p1)进入java的世界

浅谈java世界(连载中P1) Java是一门语言,它并不是很难理解的东西,语言是来进行交流的工具,那么它用来跟谁来交互呢,所有的语言都有与其交流的对象,中文也好英文也罢,交流基本的对象应…

python __setattr__ , __getattr__

Python Class 对象或类型通过内置成员 __dict__ 来存储成员信息。 我们还可以通过重载 __getattr__ 和 __setattr__ 来拦截对成员的访问,需要注意的是 __getattr__ 只有在访问不存在的成员时才会被调用。转载于:https://www.cnblogs.com/Huayuan/archive/2013/05/17…

第01章 PyTorch简介和安装 的学习笔记

由于第一章,主要介绍Pytorch的安装,而自己的笔记本已经安装了CPU版本的Pytorch,所以第一章主要是复习了Conda的基本命令并做了5个选择题供大家练习。 课程来源:https://github.com/datawhalechina/thorough-pytorch 1、在Window…

python socket tcp客户端_python网络编程socketserver模块(实现TCP客户端/服务器)

摘录python核心编程socketserver(python3.x版本重新命名)是标准库中的网络编程的高级模块。通过将创建网络客户端和服务器所必须的代码封装起来,简化了模板,为你提供了各种各样的类。除了隐藏了实现细节之外,它督促我们使用类(面向对象的思维…

template.process(root, out)的用法(shiro项目中来的九)

假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请…

java中最常用jar包的用途说明,适合初学者

jar包用途axis.jarSOAP引擎包commons-discovery-0.2.jar用来发现、查找和实现可插入式接口,提供一些一般类实例化、单件的生命周期管理的常用方法.jaxrpc.jarAxis运行所需要的组件包saaj.jar创建到端点的点到点连接的方法、创建并处理SOAP消息和附件的方法&#xff…

【青少年编程(第33周)】Scratch(三级)公益活动开营了!

2021年10月10日(周日)晚20:00我们在青少年编程竞赛交流群开展了第三十三期直播活动。我们直播活动的主要内容如下: 首先,我们奖励了上周测试超过40分的小朋友。 其次,我们讲解了上次测试中小朋友们做错的题目Scratch青…

python函数图像绘制、函数不固定_无法在函数中绘制tkinter图像

我正在制作一个垄断游戏,我试图在画布上绘制图像,但它只有在功能不起作用的情况下才会起作用:def make_image(root, location, canvas):photo PhotoImage(file root)canvas.create_image(location["X"],location["Y"],…

一些与算法有关的网站

//转自:http://www.cnblogs.com/a180285/archive/2012/01/15/2290290.html //------------------------------------------------------------------------------------------------------------------------------------------------------------ 我在网上到处找了…

【工程基础】校招研发工程师笔试题

请留言,说出你的解题思路和答案。稍后,我会把参考答案发到留言区。不定期整理相关的问题答案分享。 1、以下代码违反了什么设计原则() public class Student {public int Id;public string StudentName; }public class MClass {…

情人节学写html5微信游戏

情人节都在干什么??? 当然是写代码!!! 看某书正好以一个html5微信游戏,很适合今天的日子 附上demo:demo 请在手机上查看,pc端请切换手机调试模式,目前没弄完后…

python和idl_有前辈对比过IDL和Python的速度吗,哪个会快点?

看到这个问题,发现国外还真有人做过对比,主要在于语言特点方面,并没有详细的定量对比,贴过来大家一起乐呵乐呵。其实大体上就是之前几位答主所说的那样,主要区别在于:1.资料的多少。python资料较多2.现成的…

测试用例经验谈

1.需要测试的那个类是new出来的实例; 2.被测试的类实例的对象所需要调用的接口或者对象都是mock出来的(无论是否已经有实现)。 3.所有的接口都是根据被测试的类的需要产生的,即接口属于客户(被测试的类)。 …

中国电子学会图形化四级编程题:加减法混合运算器

「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复【Scratch】或【Python】,即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100,小马老…

Bzoj4566:[HAOI2016]找相同字符

题面 Bzoj Sol 两个串拼在一起后求出后缀数组 然后显然的\(n^2\)暴力&#xff0c;就是直接枚举求\(LCP\) 又由于扫的时候是对\(height\)取\(min\) 那么可以用单调栈维护每一段的贡献相同的 # include <bits/stdc.h> # define RG register # define IL inline # define Fi…

python字符照片_python图片转字符图片

python图片转字符图片代码话不多说&#xff0c;直接上代码。***************************#-*- coding:utf-8 -*-from PIL import ImageIMG#文件路径WIDTH60HEIGHT45ascii_char list("$B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_~<>i!lI;:,\"^…

三大基本排序专题

//以下依次是冒泡、选择、插入排序 var n,i:longint;a:array[0..20] of longint;procedure BUB;var i,j,t:longint;beginfor i:1 to n-1 dofor j:1 to n-i doif a[j]>a[j1] then begin t:a[j]; a[j]:a[j1]; a[j1]:t; end;end;procedure SEL;var i,j,k,t:longint;beginfor i:…

Linux内核中锁机制之完成量、互斥量

在上一篇博文中笔者分析了关于信号量、读写信号量的使用及源码实现&#xff0c;接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题。 八、完成量 下面讨论完成量的内容&#xff0c;首先需明确完成量表示为一个执行单元需要等待另一个执行单元完成某事后方可执行&…

中国电子学会图形化四级编程题:绳子算法

「青少年编程竞赛交流群」已成立&#xff08;适合6至18周岁的青少年&#xff09;&#xff0c;公众号后台回复【Scratch】或【Python】&#xff0c;即可进入。如果加入了之前的社群不需要重复加入。 我们将有关编程题目的教学视频已经发布到抖音号21252972100&#xff0c;小马老…

域名登陆出现400_域名解析错误怎么办?

可能有些人在进行域名解析时会遇到解析错误的问题&#xff0c;遇到这样的问题该怎么办呢&#xff1f;今天小编给大家整理了一些思路&#xff0c;希望能够提供一些帮助给大家。网站域名设置目前域名解析服务很多都是由域名供应商来设置&#xff0c;也有用户在网站运营期间需要更…

第02章 PyTorch基础知识

文章目录第02章 Pytorch基础知识2.1 张量2.2 自动求导2.3 并行计算简介2.3.1 为什么要做并行计算2.3.2 CUDA是个啥2.3.3 做并行的方法补充&#xff1a;通过股票数据感受张量概念。本图文是Datawhale组队学习Pytorch的学习笔记&#xff0c;主要内容包括张量的概念&#xff08;0维…

一个简单的缓冲区溢出的思考

从大二开始真正接触技术开始&#xff0c;从最早的HTML&#xff0c;PHP&#xff0c;WEB开发。一直以为以后可能会从事开发的工作&#xff0c;碰巧大三上的时候和同专业的郭子&#xff0c;邹豪参加了南京的一个信息安全技能大赛&#xff0c;才真正找到了兴趣的方向&#xff0c;也…

Spring-boot+Vue = Fame 写blog的一次小结

前言 作为一个程序员&#xff0c;总是要有一个属于自己的博客。然后作为一个造轮子的程序员&#xff0c;肯定不满足于直接使用现有的博客系统&#xff0c;于是我便自己写了一个带后台管理的博客系统。 体验地址&#xff1a; zzzzbw.cn 技术选型 作为一个Javaer&#xff0c;服务…

gitee查看当前账号_upic+gitee图床,自由书写Markdown

使用的软件Typora&#xff1a;Markdown文档编辑器(https://www.typora.io/)upic&#xff1a;图床工具(https://github.com/gee1k/uPic)创建自己的GitHub图床1 创建账号https://gitee.com/,自行创建账号就可以了和github很相似&#xff0c;但是速度更快2创建仓库内容按照自己的习…

CentOS中vsftp安装与配置

1. 安装 使用chkconfig --list来查看是否装有vsftpd服务&#xff1b; 使用yum命令直接安装&#xff1a;yum -y install vsftpd 然后为它创建日志文件&#xff1a;touch /var/log/vsftpd.log 这样简单的两个命令就完成了vsftp的安装&#xff0c;但是如果你现在想这样ftp://your_…

纸上原型设计 VS 桌面原型工具设计,你更喜欢谁?

2019独角兽企业重金招聘Python工程师标准>>> 纸上原型设计&#xff0c;作为传统的原型设计方式&#xff0c;简单快速&#xff0c;成本低廉&#xff0c;为大部分设计师所喜爱。而桌面原型工具设计&#xff0c;作为伴随电脑科技发展而出现的原型设计方式&#xff0c;快…

韩宇:CV学习路线

CV学习路线 对于刚入门CV的同学来说&#xff0c;通过看视频学习效率会比看书高&#xff0c;如下是我亲身实践较为高效的CV学习路线。 1. 计算机视觉概述 计算机视觉本身又包括了诸多不同的研究方向&#xff0c;比较基础和热门的几个方向主要包括&#xff1a; 物体识别和检测…