从零开始学习音视频编程技术(十八) 录屏软件开发之编码AAC

原文地址:http://blog.yundiantech.com/?log=blog&id=24

光阴似箭,日月如梭。 时间过的可真快。。。 

一转眼 大半年就过去了,差点就忘记学习了。。

学习贵在坚持和积累,然而就是很难做到坚持。。

不知不觉已经半年没有更新了,对不住大家了,赶紧继续更新。。


之前讲到了使用ffmpeg读取麦克风并保存成PCM文件。传送门


获取到了PCM之后,下一步当然是编码生成AAC了。

与之前说过的YUV是视频的原始数据类似,PCM是音频的原始数据,因此它的大小也相对比较大,因此就有必要将PCM数据编码。

同样,音频的编码方式也有很多种,常见如MP3,AAC。我们以后使用比较多的就是AAC,因此本文只讲解将pcm编码成AAC。



编码aac一样还是直接使用ffmpeg,方法如下:


1.查找并打开AAC编码器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
     AVCodecContext* pCodecCtx;    AVCodec* aCodec;
 
     uint8_t* frame_buf;
     AVFrame* frame;
     int  ONEFrameSize;
 
     pCodecCtx = avcodec_alloc_context3(aCodec);
     pCodecCtx->codec_id = AV_CODEC_ID_AAC;
     pCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
     pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
     pCodecCtx->sample_rate= 44100;
     pCodecCtx->channel_layout=AV_CH_LAYOUT_STEREO;
     pCodecCtx->channels = av_get_channel_layout_nb_channels(pCodecCtx->channel_layout);
     pCodecCtx->bit_rate = 64000;
 
 
     aCodec = avcodec_find_encoder(pCodecCtx->codec_id);
     if  (!aCodec)
     {
         printf ("没有找到合适的编码器!
");
         return ;
     }
     if  (avcodec_open2(pCodecCtx, aCodec,NULL) < 0)
     {
         printf ("编码器打开失败!
");
         return ;
     }


上面设置的

1
2
3
     pCodecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
     pCodecCtx->sample_rate= 44100;
     pCodecCtx->channel_layout=AV_CH_LAYOUT_STEREO;

这三个必须要和原始PCM数据的一致,否则编码后的音频播放会有问题。

本文提供的例子是直接用ffmpeg采集后得到的pcm,因此默认都是16bit、44100HZ、双声道的数据,至于ffmpeg采集的时候如果修改这个信息,我也没有研究,以后有时间再去看了,这里暂时不管他了。



2.编码器成功打开之后就是进行编码了,编码使用的函数是:avcodec_encode_audio2


这里需要注意的是:

传递给ffmpeg编码的Pcm数据,每次的大小必须是下面这个值。

1
     ONEFrameSize = av_samples_get_buffer_size(NULL, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);

至于不是这个会出现什么问题,我也忘记了,很久以前写的了,只记得这里要是这个值。 

有兴趣的自己去试一试会是什么结果吧。


由于ffmpeg采集音频的时候,一次获取到的pcm数据不一定是这个大小(实际上是肯定不是),因此需要手动处理一下,大致代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
     AVPacket pkt;    
     av_new_packet(&pkt,ONEFrameSize);
 
     FILE  *aacFp =  fopen ( "out.aac" , "wb" );
 
     uint8_t * mAacBuffer = (uint8_t * ) malloc (4096*100);
     int  mAacBufferIndex = 0;
     int  mAacBufferSize = 0;
 
     while (1)
     {
         if  (mPcmBufferList.isEmpty())
         {
             msleep(10);
             continue ;
         }
 
         mMutex.lock();
         FrameDataNode node = mPcmBufferList.takeFirst();  //取出1帧yuv数据
         mMutex.unlock();
 
         memcpy (mAacBuffer+mAacBufferSize,node.buffer,node.size);
         mAacBufferSize += node.size;
         free (node.buffer);
 
         /// 每次传递给编码器的数据大小都要是 上面获取到的 "ONEFrameSize"
         /// 因此需要下面的循环
         while (1)
         {
             int  size = mAacBufferSize - mAacBufferIndex;
             if  (size < ONEFrameSize)  //不够编码1帧了
             {
                 memcpy (mAacBuffer,mAacBuffer+mAacBufferIndex,size);
                 mAacBufferIndex = 0;
                 mAacBufferSize = size;
                 break ;
             }
 
             frame->data[0] = mAacBuffer+mAacBufferIndex;   //采样信号
             mAacBufferIndex += ONEFrameSize;
 
             int  got_frame=0;
 
             //编码
             int  ret = avcodec_encode_audio2(pCodecCtx, &pkt,frame, &got_frame);
             if  (got_frame==1)
             {
                 /// 编码后的数据是带ADTS头的 因此写入文件后 可以直接用播放器播放
                 fwrite (pkt.data,1,pkt.size,aacFp);
 
                 av_free_packet(&pkt);
             }
         }
     }


这个代码相对比较简单,具体的就不做解释了,请下载完整工程查看吧。

完整工程下载地址:http://download.csdn.net/detail/qq214517703/9823988

音视频技术交流讨论欢迎加 QQ群 121376426


原文地址:http://blog.yundiantech.com/?log=blog&id=24


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
敬告:该系列的课程在抓紧录制更新中,敬请大家关注。敬告: 该系列的课程涉及:FFmpeg,WebRTC,SRS,Nginx,Darwin,Live555,等。包括:音视频、流媒体、直播、Android、视频监控28181、等。  我将带领大家一起来学习:采集麦克风、PCM重采样、AAC或MP3音频编码存储、并直播。具体内容包括:1.FFmpeg采集麦克风并存储为PCM。2.PCM重采样原理及实战。3.采集麦克风并实时转码AAC或MP3并保存文件。4.采集麦克风并实时转码AAC并可以直播。 音视频与流媒体是一门很复杂的技术,涉及的概念、原理、理论非常多,很多初学者不学 基础理论,而是直接做项目,往往会看到c/c++的代码时一头雾水,不知道代码到底是什么意思,这是为什么呢? 因为没有学习音视频和流媒体的基础理论,就比如学习英语,不学习基本单词,而是天天听英语新闻,总也听不懂。所以呢,一定要认真学习基础理论,然后再学习播放器、转码器、非编、流媒体直播、视频监控、等等。 梅老师从事音视频与流媒体行业18年;曾在永新视博、中科大洋、百度、美国Harris广播事业部等公司就职,经验丰富;曾亲手主导广电直播全套项目,精通h.264/h.265/aac,曾亲自参与百度app上的网页播放器等实战产品。 目前全身心自主创业,主要聚焦音视频+流媒体行业,精通音视频加密、流媒体在线转码快编等热门产品。
Qt是一种跨平台的应用程序开发框架,它可以用于开发各种类型的软件。如果使用Qt编写录屏软件的话,可以实现抓屏和合成视频的功能。 首先,Qt提供了Qt Multimedia模块,该模块中包含了对音频和视频的控制和处理功能。通过使用Qt的媒体类,可以实现录制屏幕上的内容,并将其保存为视频文件。 其次,Qt还提供了Qt GUI模块,通过使用该模块中的图形界面组件,可以实现用户界面的设计和交互。在录屏软件中,可以使用Qt的图形界面来创建一个用户友好的界面,其中包含开始录制、暂停录制、停止录制等功能按钮。 在录制过程中,通过调用Qt的图像处理类,可以实现抓取屏幕上的图像,并将其保存在内存中或者直接保存为图像文件。同时,可以使用Qt的定时器功能,定时抓取屏幕上的图像,以保证录制得到的视频流畅度。 在合成视频方面,Qt提供了Qt Multimedia模块中的视频处理类,可以将抓取到的图像序列合成为视频文件。通过设置视频的帧率、分辨率等参数,可以实现合成视频的定制化。 最后,结合Qt的文件操作类,可以将录制的视频文件保存到指定的位置,并进行管理和分享等操作。 总而言之,通过使用Qt开发录屏软件,可以方便快捷地实现抓屏和合成视频的功能,并且可以跨平台运行,使得用户能够在不同的操作系统上使用该软件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值