#include "stdafx.h"
#include "CMediaFileRecorder.h"
#include <windows.h>
#include <MMSystem.h>
#include "log.h"
void av_log_cb(void* data, int level, const char* msg, va_list args)
{
char log[1024] = { 0 };
vsprintf_s(log, msg, args);
if (level > AV_LOG_INFO)
MediaFileRecorder::call_log_func(MediaFileRecorder::LOG_DEBUG, msg, args);
else if (level == AV_LOG_INFO)
MediaFileRecorder::call_log_func(MediaFileRecorder::LOG_INFO, msg, args);
else if (level == AV_LOG_WARNING)
MediaFileRecorder::call_log_func(MediaFileRecorder::LOG_WARNING, msg, args);
else if (level < AV_LOG_WARNING)
MediaFileRecorder::call_log_func(MediaFileRecorder::LOG_ERROR, msg, args);
}
namespace MediaFileRecorder
{
CMediaFileRecorder::CMediaFileRecorder()
:m_bInited(false),
m_pFormatCtx(NULL),
m_pVideoCodecCtx(NULL),
m_pAudioCodecCtx(NULL),
m_pVideoPacket(NULL),
m_pAudioPacket(NULL),
m_nVideoStreamIndex(0),
m_nAudioStreamIndex(0),
m_nStartTime(0),
m_nDuration(0),
m_nVideoPacketIndex(0),
m_nAudioPacketIndex(0),
m_pVideoRecorder(new CVideoRecord()),
m_pMicRecorder(new CAudioRecord()),
m_pSpeakerRecorder(new CAudioRecord()),
m_nMainAudioStream(0)
{
m_bRun = false;
av_log_set_callback(av_log_cb);
}
CMediaFileRecorder::~CMediaFileRecorder()
{
if (m_bInited)
{
UnInit();
}
}
int CMediaFileRecorder::Init(const RECORD_INFO& record_info)
{
if (m_bInited)
{
Error("Inited already!");
return -1;
}
int ret = 0;
m_stRecordInfo = record_info;
av_register_all();
ret = avformat_alloc_output_context2(&m_pFormatCtx, NULL, NULL, m_stRecordInfo.file_name);
if (ret < 0)
{
Error("avformat_alloc_output_context2, ret: %d", ret);
CleanUp();
return -1;
}
ret = avio_open2(&m_pFormatCtx->pb, m_stRecordInfo.file_name, AVIO_FLAG_READ_WRITE, NULL, NULL);
if (ret < 0)
{
Error("avio_open failed, ret: %d", ret);
CleanUp();
return -1;
}
if (m_stRecordInfo.is_record_video)
{
if (InitVideoRecord() != 0)
{
Error("Init video record failed");
}
}
if (m_stRecordInfo.is_record_mic || m_stRecordInfo.is_record_speaker)
{
if (InitAudioRecord() != 0)
{
Error("Init audio record failed");
}
}
InitializeCriticalSection(&m_WriteFileSection);
//write file header
avformat_write_header(m_pFormatCtx, NULL);
m_bInited = true;
Info("Init media file recorder succeed!");
return 0;
}
int CMediaFileRecorder::InitVideoRecord()
{
AVStream* pVideoStream = avformat_new_stream(m_pFormatCtx, NULL);
if (pVideoStream == NULL)
{
Error("Create new video stream failed\n");
VideoCleanUp();
return -1;
}
m_nVideoStreamIndex = m_pFormatCtx->nb_streams - 1;
/*m_pVideoCodecCtx = avcodec_alloc_context3(NULL);
if (!m_pVideoCodecCtx)
{
Error("Create video codec context failed");
VideoCleanUp();
return -1;
}
avcodec_parameters_to_context(m_pVideoCodecCtx, pVideoStream->codecpar);*/
m_pVideoCodecCtx = pVideoStream->codec;
AVCodecID avcodecid = AV_CODEC_ID_H264;
switch (m_stRecordInfo.format)
{
case VIDEO_FORMAT_H264_MP4:
avcodecid = AV_CODEC_ID_H264;
break;
case VIDEO_FORMAT_MPEG4_MP4:
avcodecid = AV_CODEC_ID_MPEG4;
break;
case VIDEO_FORMAT_MPEG4_AVI:
avcodecid = AV_CODEC_ID_MPEG4;
break;
case VIDEO_FORMAT_H264_AVI:
avcodecid = AV_CODEC_ID_H264;
break;
case VIDEO_FORMAT_FLV:
avcodecid = AV_CODEC_ID_FLV1;
break;
case VIDEO_FORMAT_WMV:
avcodecid = AV_CODEC_ID_WMV2;
break;
default:
break;
}
m_pVideoCodecCtx->codec_id = avcodecid;
m_pVideoCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
m_pVideoCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
m_pVideoCodecCtx->width = m_stRecordInfo.video_dst_width;
m_pVideoCodecCtx->height = m_stRecordInfo.video_dst_height;
m_pVideoCodecCtx->time_base.num = 1;
m_pVideoCodecCtx->time_base.den = m_stRecordInfo.video_frame_rate;
m_pVideoCodecCtx->thread_count = m_stRecordInfo.thread_count;
m_pVideoCodecCtx->qcompress = (float)0.6;
m_pVideoCodecCtx->max_qdiff = 4;
m_pVideoCodecCtx->qmin = 0;
m_pVideoCodecCtx->qmax = 50;
m_pVideoCodecCtx->delay = 0;
m_pVideoCodecCtx->keyint_min = m_stRecordInfo.video_frame_rate;
m_pVideoCodecCtx->gop_size = m_stRecordInfo.video_frame_rate * 10;
const char* crf = "23";
if (m_stRecordInfo.quality == NORMAL)
{
crf = "28";
}
else if (m_stRecordInfo.quality == HIGH)
{
crf = "23";
}
else if (m_stRecordInfo.quality == VERY_HIGH)
{
crf = "18";
}
AVDictionary *param = 0;
av_dict_set(¶m, "preset", "veryfast", 0);
av_dict_set(¶m, "tune", "zerolatency", 0);
av_dict_set(¶m, "crf", crf, 0);
AVCodec* pEncoder = avcodec_find_encoder(m_pVideoCodecCtx->codec_id);
if (!pEncoder)
{
Error("avcodec_findo_encoder failed\n");
VideoCleanUp();
return -1;
}
if (m_pFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
m_pVideoCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
int ret = avcodec_open2(m_pVideoCodecCtx, pEncoder, ¶m);
if (ret < 0)
{
Error("avcodec_open2 failed, ret: %d", ret);
VideoCleanUp();
return -1;
}
int nPicSize = av_image_get_buffer_size(m_pVideoCodecCtx->pix_fmt, m_pVideoCodecCtx->width, m_pVideoCodecCtx->height, 1);
m_pVideoPacket = av_packet_alloc();
av_new_packet(m_pVideoPacket, nPicSize);
ret = m_pVideoRecorder->Init(m_pVideoCodecCtx);
if (ret != 0)
{
Error("Failed to init video recorder");
return -1;
}
return 0;
}
void CMediaFileRecorder::UnInitVideoRecord()
{
m_pVideoRecorder->UnInit();
Info("Write video packet count: %lld", m_nVideoPacketIndex);
VideoCleanUp();
}
void CMediaFileRecorder::VideoCleanUp()
{
if (m_pVideoPacket)
{
av_packet_unref(m_pVideoPacket);
av_packet_free(&m_pVideoPacket);
m_pVideoPacket = NULL;
}
if (m_pVideoCodecCtx)
{
avcodec_close(m_pVideoCodecCtx);
m_pVideoCodecCtx = NULL;
}
m_nVideoPacketIndex = 0;
}
int CMediaFileRecorder::InitAudioRecord()
{
AVStream* pStream = avformat_new_stream(m_pFormatCtx, NULL);
if (!pStream)
{
Error("Create audio stream failed! \n");
AudioCleanUp();
return -1;
}
m_nAudioStreamIndex = m_pFormatCtx->nb_streams - 1;
/*m_pAudioCodecCtx = avcodec_alloc_context3(NULL);
if (!m_pAudioCodecCtx)
{
Error("Create audio codec context failed");
return -1;
}
avcodec_parameters_to_context(m_pAudioCodecCtx, pStream->codecpar);*/
m_pAudioCodecCtx = pStream->codec;
m_pAudioCodecCtx->codec_id = AV_CODEC_ID_AAC;
m_pAudioCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
m_pAudioCodecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;
m_pAudioCodecCtx->sample_rate = 44100;
m_pAudioCodecCtx->channel_layout = AV_CH_LAYOUT_STEREO;
m_pAudioCodecCtx->channels = av_get_channel_layout_nb_channels(m_pAudioCodecCtx->channel_layout);
//m_pAudioCodecCtx->bit_rate = 128000;
AVCodec* audio_encoder = avcodec_find_encoder(m_pAudioCodecCtx->codec_id);
if (!audio_encoder)
{
Error("Failed to find audio encoder! \n");
AudioCleanUp();
return -1;
}
if (m_pFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
{
m_pAudioCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
if (avcodec_open2(m_pAudioCodecCtx, audio_encoder, NULL) < 0)
{
Error("Failed to open audio codec context");
AudioCleanUp();
return -1;
}
int nAudioSize = av_samples_get_buffer_size(NULL, m_pAudioCodecCtx->channels,
m_pAudioCodecCtx->frame_size, m_pAudioCodecCtx->sample_fmt, 1);
m_pAudioPacket = av_packet_alloc();
av_new_packet(m_pAudioPacket, nAudioSize);
//av_new_packet(m_pAudioPacket, nAudioSize);
if (m_stRecordInfo.is_record_mic)
{
if (m_pMicRecorder->Init(m_pAudioCodecCtx) != 0)
{
Error("Failed to init mic recorder \n");
}
}
if (m_stRecordInfo.is_record_speaker)
{
if (m_pSpeakerRecorder->Init(m_pAudioCodecCtx) != 0)
{
Error("Failed to init speaker recorder \n");
}
}
return 0;
}
void CMediaFileRecorder::UnInitAudioRecord()
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
这是一个基于FFmpeg使用 C# 、C++ 开发的最简单的屏幕录制软件。.zip (533个子文件)
DefaultWsdlHelpGenerator.aspx 59KB
Compat.browser 2KB
machine.config 28KB
web.config 11KB
config 2KB
App.config 178B
CMediaFileRecorder.cpp 31KB
audio_mixer.cpp 20KB
ScreenAndAudioCapture.cpp 16KB
Recorder.cpp 12KB
App.cpp 12KB
CWASAudioCapture.cpp 11KB
CWAVEAudioCapture.cpp 9KB
CScreenDXGIGrabber.cpp 8KB
CScreenAudioRecord.cpp 8KB
Utils.cpp 7KB
ScreenRecoder.cpp 5KB
system_info.cpp 5KB
StringHlp.cpp 5KB
CScreenDXGrabber.cpp 4KB
CScreenGdiGrabber.cpp 4KB
log.cpp 2KB
CScreenAudioRecord_C.cpp 2KB
AudioCaptureFactory.cpp 562B
ScreenGrabberFactory.cpp 449B
dllmain.cpp 370B
stdafx.cpp 328B
stdafx.cpp 219B
screen_audio_recorder.cpp 87B
FormSettings.Designer.cs 61KB
FormMain.cs 33KB
FormMain.Designer.cs 31KB
FormScreenShutcut.cs 30KB
Resources.Designer.cs 30KB
FormEditScreenShutTools.Designer.cs 23KB
FormRect.cs 13KB
FormSettings.cs 13KB
FormEditScreenShutTools.cs 12KB
ImageButton.cs 10KB
FormMsg.Designer.cs 10KB
Settings.cs 9KB
FormMsgSmall.Designer.cs 8KB
FormRect.Designer.cs 8KB
FormDebug.Designer.cs 8KB
FileBorserDialog.cs 8KB
PaintBox.cs 7KB
FormRecMini.Designer.cs 7KB
FormChooseWindow.cs 5KB
HotKeySelecter.cs 4KB
FormColorPick.Designer.cs 4KB
Toggle.Designer.cs 4KB
Recorder.cs 4KB
FormColorPick.cs 3KB
FormScreenShutcut.Designer.cs 3KB
FlatButton.cs 3KB
API.cs 3KB
PaintMosaic.cs 2KB
FormChooseWindow.Designer.cs 2KB
FormMsgSmall.cs 2KB
FormRecMini.cs 2KB
TabButton.cs 2KB
DebugUtils.cs 2KB
ColorToolbar.cs 2KB
FormMsg.cs 2KB
IconButton.Designer.cs 2KB
Taber.cs 2KB
FormRectRecing.designer.cs 2KB
PaintText.cs 2KB
AppUtils.cs 2KB
PaintObject.cs 2KB
IconButton.cs 1KB
CheckGroup.cs 1KB
PaintArrow.cs 1KB
FormDebug.cs 1KB
AssemblyInfo.cs 1KB
Toggle.cs 1KB
WindowUtils.cs 1KB
Settings.Designer.cs 1KB
Program.cs 1KB
PaintPen.cs 897B
Utils.cs 701B
FormRectRecing.cs 687B
PaintEllipse.cs 515B
PaintRectangle.cs 515B
PaintTypes.cs 406B
DialogUtils.cs 292B
ScreenRecoder.App.csproj 14KB
ScreenRecoder.AppForMonoDevelop.csproj 13KB
cur_pen.cur 2KB
cur_default.cur 2KB
cur_brush_big.cur 326B
cur_brush_normal.cur 326B
cur_brush_small.cur 326B
avcodec-57.dll 11.14MB
avcodec-57.dll 11.14MB
mono.dll 5.12MB
mscorlib.dll 4.88MB
System.Xml.dll 3.03MB
System.Windows.Forms.dll 2.77MB
System.dll 2.47MB
共 533 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论
JJJ69
- 粉丝: 6232
- 资源: 5778
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功