extern "C"
{
#include "libavformat\avformat.h"
#include "libavdevice\avdevice.h"
#include "libswscale\swscale.h"
};
//录制屏幕为TS视频流(分辨率调整为352*288)
int ScreenToTS()
{
//依当前本地时间生出输出文件路径
time_t LocalTime = time(0);
char LocalTimeBuf[32] = "";
strftime(LocalTimeBuf,sizeof(LocalTimeBuf),"%Y_%m_%d_%H_%M_%S",localtime(&LocalTime));
char ts_out_path[32] = "";
sprintf(ts_out_path,"%s.ts",LocalTimeBuf);
//锁定输出文件格式
AVFormatContext* pFormatContext_Out = NULL;
avformat_alloc_output_context2(&pFormatContext_Out,NULL,NULL,ts_out_path);
if(!pFormatContext_Out)
return -1;
AVOutputFormat* pOutputFormat = NULL;
pOutputFormat = pFormatContext_Out->oformat;
//找到输出文件格式对应的编码器
AVCodec* pCodec_Out = NULL;
pCodec_Out = avcodec_find_encoder(pOutputFormat->video_codec);
//依输出文件编码器创建输出流
AVStream* pStream_Out = NULL;
pStream_Out = avformat_new_stream(pFormatContext_Out,pCodec_Out);
if(!pStream_Out)
{
avformat_free_context(pFormatContext_Out);
return -2;
}
//设定输出文件编解码器上下文环境
AVCodecContext* pCodecContext_Out = NULL;
pCodecContext_Out = pStream_Out->codec;
pCodecContext_Out->codec_id = pOutputFormat->video_codec;
pCodecContext_Out->bit_rate = 200000;
pCodecContext_Out->width = 352;
pCodecContext_Out->height = 288;
pStream_Out->time_base.num = 1;
pStream_Out->time_base.den = 10;
pCodecContext_Out->time_base = pStream_Out->time_base;
pCodecContext_Out->gop_size = 250;
pCodecContext_Out->pix_fmt = AV_PIX_FMT_YUV420P;
pCodecContext_Out->max_b_frames = 2;
pCodecContext_Out->codec_type = AVMEDIA_TYPE_VIDEO;
if(pFormatContext_Out->oformat->flags & AVFMT_GLOBALHEADER)
pCodecContext_Out->flags |= CODEC_FLAG_GLOBAL_HEADER;
//打开输出文件对应的编码器
AVDictionary *pDictionary_Out = NULL;
av_dict_copy(&pDictionary_Out,NULL,0);
if(avcodec_open2(pCodecContext_Out,pCodec_Out,&pDictionary_Out) < 0)
{
av_dict_free(&pDictionary_Out);
avformat_free_context(pFormatContext_Out);
return -3;
}
av_dict_free(&pDictionary_Out);
//截屏方式作为输入并打开该输入
AVFormatContext *pFormatContext_In = NULL;
AVDictionary* pDictionary_In = NULL;
av_dict_set(&pDictionary_In,"framerate","10",0);
AVInputFormat* pInputFormat = av_find_input_format("gdigrab");
if(avformat_open_input(&pFormatContext_In,"desktop",pInputFormat,&pDictionary_In) != 0)
{
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -4;
}
if(avformat_find_stream_info(pFormatContext_In,NULL) < 0)
{
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -5;
}
//打开输入文件对应解码器
AVCodecContext* pCodecContext_In = NULL;
pCodecContext_In = pFormatContext_In->streams[0]->codec;
AVCodec* pCodec_In = NULL;
pCodec_In = avcodec_find_decoder(pCodecContext_In->codec_id);
if(avcodec_open2(pCodecContext_In,pCodec_In,nullptr)!=0)
{
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -6;
}
//申请帧缓存(bmp帧、调整分辨率之后的yuv420p帧)
AVFrame *pFrame,*pFrameYuv;
pFrame = av_frame_alloc();
pFrameYuv = av_frame_alloc();
if((pFrame == NULL) || (pFrameYuv == NULL))
{
avcodec_close(pCodecContext_In);
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -7;
}
pFrameYuv->format = pCodecContext_Out->pix_fmt;
pFrameYuv->width = pCodecContext_Out->width;
pFrameYuv->height = pCodecContext_Out->height;
int Yuv420pSize = avpicture_get_size(PIX_FMT_YUV420P,pCodecContext_Out->width,pCodecContext_Out->height);
uint8_t* Yuv420pBuf = (uint8_t* )av_malloc(Yuv420pSize);
avpicture_fill((AVPicture* )pFrameYuv,Yuv420pBuf,PIX_FMT_YUV420P,pCodecContext_Out->width,pCodecContext_Out->height);
//创建数据缓存并初始化
AVPacket pPacket;
av_init_packet(&pPacket);
pPacket.data = NULL;
pPacket.size = 0;
//打开输出流
if(avio_open(&pFormatContext_Out->pb,ts_out_path,AVIO_FLAG_WRITE) < 0)
{
av_free(Yuv420pBuf);
av_frame_free(&pFrameYuv);
av_frame_free(&pFrame);
avcodec_close(pCodecContext_In);
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -8;
}
//写输出流的头部数据
if(avformat_write_header(pFormatContext_Out,&pDictionary_Out) < 0)
{
avio_closep(&pFormatContext_Out->pb);
av_free(Yuv420pBuf);
av_frame_free(&pFrameYuv);
av_frame_free(&pFrame);
avcodec_close(pCodecContext_In);
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -9;
}
//对输入视频流解码,编码视频帧序列到输出流
int ReturnValue = 0,got_picture_ptr = 0;
while(pStream_Out->codec->frame_number < 600)
{
if(av_read_frame(pFormatContext_In,&pPacket) >= 0)
{
if(pPacket.stream_index == 0)
{
if((ReturnValue = avcodec_decode_video2(pCodecContext_In,pFrame,&got_picture_ptr,&pPacket)) < 0)
{
avio_closep(&pFormatContext_Out->pb);
av_free(Yuv420pBuf);
av_frame_free(&pFrameYuv);
av_frame_free(&pFrame);
avcodec_close(pCodecContext_In);
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -10;
}
if(got_picture_ptr)
{
struct SwsContext* pSwsContext = sws_getContext(pCodecContext_In->width,pCodecContext_In->height,pCodecContext_In->pix_fmt,pCodecContext_Out->width,pCodecContext_Out->height,PIX_FMT_YUV420P,SWS_SINC,NULL,NULL,NULL);
sws_scale(pSwsContext,(const uint8_t* const*)pFrame->data,pFrame->linesize,0,pCodecContext_In->height,pFrameYuv->data,pFrameYuv->linesize);
sws_freeContext(pSwsContext);
if(avcodec_encode_video2(pCodecContext_Out,&pPacket,pFrameYuv,&got_picture_ptr) < 0)
{
avio_closep(&pFormatContext_Out->pb);
av_free(Yuv420pBuf);
av_frame_free(&pFrameYuv);
av_frame_free(&pFrame);
avcodec_close(pCodecContext_In);
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return -11;
}
if(got_picture_ptr)
{
av_packet_rescale_ts(&pPacket,pCodecContext_Out->time_base,pStream_Out->time_base);
pPacket.stream_index = pStream_Out->index;
av_interleaved_write_frame(pFormatContext_Out,&pPacket);
}
}
}
av_free_packet(&pPacket);
}
else
break;
}
//写输出流的尾部数据
av_write_trailer(pFormatContext_Out);
//资源释放
avio_closep(&pFormatContext_Out->pb);
av_free(Yuv420pBuf);
av_frame_free(&pFrameYuv);
av_frame_free(&pFrame);
avcodec_close(pCodecContext_In);
avformat_close_input(&pFormatContext_In);
avcodec_close(pCodecContext_Out);
avformat_free_context(pFormatContext_Out);
return 0;
}
int main()
{
av_register_all();
avdevice_register_all();
if(ScreenToTS() == 0)
system("PAUSE");
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
FFmpeg_屏幕录制为TS流(可拼接版)
共224个文件
h:98个
tlog:90个
lib:8个
3星 · 超过75%的资源 需积分: 48 38 下载量 22 浏览量
2015-09-09
15:44:40
上传
评论
收藏 14.27MB ZIP 举报
温馨提示
vc2010下,之前的那一版,生成的TS流无法很好拼接,这一版解决了这个问题,其实也就参数设置不对,不过,一句话,就能解决一个重要问题,2分还是要的
资源推荐
资源详情
资源评论
收起资源包目录
FFmpeg_屏幕录制为TS流(可拼接版) (224个子文件)
FFmpeg.cpp 7KB
Thumbs.db 16KB
avcodec-56.dll 21.33MB
avformat-56.dll 5.73MB
avfilter-5.dll 2.28MB
avdevice-56.dll 1.32MB
avutil-54.dll 482KB
swscale-3.dll 442KB
swresample-1.dll 275KB
postproc-53.dll 129KB
FFmpeg.exe 34KB
FFmpeg.vcxproj.filters 955B
avcodec.h 178KB
avformat.h 103KB
avfilter.h 56KB
opt.h 37KB
pixfmt.h 34KB
frame.h 24KB
avio.h 22KB
swresample.h 20KB
intreadwrite.h 18KB
avdevice.h 18KB
pixdesc.h 15KB
mem.h 14KB
common.h 14KB
old_pix_fmts.h 14KB
avstring.h 13KB
swscale.h 12KB
log.h 10KB
old_codec_ids.h 10KB
samplefmt.h 10KB
buffer.h 10KB
channel_layout.h 9KB
avutil.h 8KB
imgutils.h 8KB
_mingw.h 8KB
vdpau.h 8KB
dict.h 8KB
bprint.h 8KB
parseutils.h 7KB
buffersink.h 7KB
version.h 6KB
xvmc.h 6KB
vda.h 6KB
stdint.h 6KB
inttypes.h 6KB
error.h 5KB
timecode.h 5KB
eval.h 5KB
mathematics.h 5KB
fifo.h 5KB
cpu.h 5KB
buffersrc.h 5KB
audio_fifo.h 4KB
rational.h 4KB
attributes.h 4KB
version.h 4KB
vaapi.h 4KB
dv_profile.h 4KB
stereo3d.h 4KB
hash.h 4KB
asrc_abuffer.h 3KB
downmix_info.h 3KB
display.h 3KB
threadmessage.h 3KB
avfft.h 3KB
postprocess.h 3KB
version.h 3KB
hmac.h 3KB
bswap.h 3KB
crc.h 3KB
timestamp.h 3KB
cast5.h 2KB
d3d11va.h 2KB
file.h 2KB
version.h 2KB
avcodec.h 2KB
dxva2.h 2KB
vorbis_parser.h 2KB
blowfish.h 2KB
twofish.h 2KB
camellia.h 2KB
avassert.h 2KB
base64.h 2KB
pixelutils.h 2KB
lzo.h 2KB
sha512.h 2KB
ripemd.h 2KB
version.h 2KB
lfg.h 2KB
md5.h 2KB
sha.h 2KB
xtea.h 2KB
version.h 2KB
aes.h 2KB
time.h 2KB
intfloat.h 2KB
version.h 2KB
version.h 2KB
replaygain.h 2KB
共 224 条
- 1
- 2
- 3
资源评论
- sinat_348494212020-08-05可以录制屏幕为ts文件,但是画面很模糊
- qtc++开发者2021-07-1449分过分了
黄忻
- 粉丝: 27
- 资源: 108
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功