#include "AVUtils.h"
bool AVUtils::isInit = false;
AVUtils::AVUtils() : mPlayerState(VideoPlayer_Stop),
mConditon_Audio(new WaitCondition),
mConditon_Video(new WaitCondition),
mAudioID(0),
mIsNeedPause(false),
mVolume(1),
mIsQuit(false),
mIsMute(false),
mIsPause(false),
mPauseStartTime(0)
{
init();
}
AVUtils::~AVUtils()
{
av_lockmgr_register(NULL);
avformat_network_deinit();
}
bool AVUtils::init()
{
if (!isInit)
{
av_register_all();
avformat_network_init();
isInit = true;
}
return isInit;
}
bool AVUtils::start(std::string filePath)
{
if (mPlayerState != VideoPlayer_Stop)
return false;
mIsQuit = false;
mIsPause = false;
if (!filePath.empty())
this->filePath = filePath;
std::thread([&](AVUtils *avutils)
{
avutils->readVideoFile();
}, this).detach();
return true;
}
bool AVUtils::replay()
{
stop();
start(filePath);
return true;
}
bool AVUtils::play()
{
if (mPlayerState != VideoPlayer_Pause)
return false;
mIsNeedPause = false;
mIsPause = false;
uint64_t pauseTime = av_gettime() - mVideoStartTime; //暂停了多长时间
mVideoStartTime += pauseTime; //将暂停的时间加到开始播放的时间上,保证同步不受暂停的影响
mPlayerState = VideoPlayer_Playing;
doPlayerStateChanged(VideoPlayer_Playing, mVideoStream != nullptr, mAudioStream != nullptr);
return true;
}
bool AVUtils::puase()
{
mIsPause = true;
if (mPlayerState != VideoPlayer_Playing)
return false;
mPauseStartTime = av_gettime();
mPlayerState = VideoPlayer_Pause;
doPlayerStateChanged(VideoPlayer_Pause, mVideoStream != nullptr, mAudioStream != nullptr);
return true;
}
bool AVUtils::stop(bool isWait)
{
if (mPlayerState == VideoPlayer_Stop)
return false;
mPlayerState = VideoPlayer_Stop;
mIsQuit = true;
if (!isWait)
return true;
while (!mIsReadThreadFinished)
QThread::msleep(5);
return true;
}
void AVUtils::seek(int64_t pos)
{
if (!seek_req)
{
seek_pos = pos;
seek_req = 1;
}
}
void AVUtils::setMute(bool isMute)
{
this->mIsMute = isMute;
}
void AVUtils::setVolume(float value)
{
mVolume = value;
}
float AVUtils::getVolume()
{
return mVolume;
}
int64_t AVUtils::getTotalTime()
{
if (pFormatCtx != nullptr)
return pFormatCtx->duration;
return 0;
}
double AVUtils::getCurrentTime()
{
return audio_clock;
}
VideoPlayerState AVUtils::getState()
{
return this->mPlayerState;
}
void AVUtils::readVideoFile()
{
///SDL初始化需要放入子线程中,否则有些电脑会有问题。
if (SDL_Init(SDL_INIT_AUDIO))
{
doOpenSdlFailed(-100);
fprintf(stderr, "Could not initialize SDL - %s. \n", SDL_GetError());
return;
}
mIsReadThreadFinished = false;
mIsReadFinished = false;
const char* file_path = filePath.c_str();
pFormatCtx = nullptr;
pCodecCtx = nullptr;
pCodec = nullptr;
aCodecCtx = nullptr;
aCodec = nullptr;
aFrame = nullptr;
swrCtx = nullptr;
mAudioStream = nullptr;
mVideoStream = nullptr;
audio_clock = 0;
video_clock = 0;
int audioStream, videoStream;
//Allocate an AVFormatContext.
pFormatCtx = avformat_alloc_context();
AVDictionary* opts = NULL;
av_dict_set(&opts, "rtsp_transport", "tcp", 0);//设置tcp or udp,默认一般优先tcp再尝试udp
av_dict_set(&opts, "stimeout", "60000000", 0);//设置超时3秒
if (avformat_open_input(&pFormatCtx, file_path, nullptr, &opts) != 0)
{
fprintf(stderr, "can't open the file. \n");
doOpenVideoFileFailed();
goto end;
}
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0)
{
fprintf(stderr, "Could't find stream infomation.\n");
doOpenVideoFileFailed();
goto end;
}
videoStream = -1;
audioStream = -1;
///循环查找视频中包含的流信息,
for (int i = 0; i < pFormatCtx->nb_streams; i++)
{
AVMediaType media_type = pFormatCtx->streams[i]->codec->codec_type;
if (media_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
}
else if (media_type == AVMEDIA_TYPE_AUDIO)
{
audioStream = i;
}
if (videoStream > 0 && audioStream > 0)
{
break;
}
}
doTotalTimeChanged(getTotalTime());
///打开视频解码器,并启动视频线程
if (videoStream >= 0)
{
///查找视频解码器
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == nullptr)
{
fprintf(stderr, "PCodec not found.\n");
doOpenVideoFileFailed();
goto end;
}
///打开视频解码器
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
fprintf(stderr, "Could not open video codec.\n");
doOpenVideoFileFailed();
goto end;
}
mVideoStream = pFormatCtx->streams[videoStream];
///创建一个线程专门用来解码视频
std::thread([&](AVUtils* avutil) {
avutil->decodeVideoThread();
}, this).detach();
}
if (audioStream >= 0)
{
///查找音频解码器
aCodecCtx = pFormatCtx->streams[audioStream]->codec;
aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
if (aCodec == NULL)
{
fprintf(stderr, "ACodec not found.\n");
audioStream = -1;
}
else
{
///打开音频解码器
if (avcodec_open2(aCodecCtx, aCodec, nullptr) < 0)
{
fprintf(stderr, "Could not open audio codec.\n");
doOpenVideoFileFailed();
goto end;
}
///解码音频相关
aFrame = av_frame_alloc();
aFrame_ReSample = nullptr;
//frame->16bit 44100 PCM 统一音频采样格式与采样率
swrCtx = nullptr;
//输出的声道布局
out_ch_layout = av_get_default_channel_layout(audio_tgt_channels); ///AV_CH_LAYOUT_STEREO
out_ch_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
/// 这里音频播放使用了固定的参数
/// 强制将音频重采样成44100 双声道 AV_SAMPLE_FMT_S16
/// SDL播放中也是用了同样的播放参数
//重采样设置选项----------------
//输入的采样格式
in_sample_fmt = aCodecCtx->sample_fmt;
//输出的采样格式 16bit PCM
out_sample_fmt = AV_SAMPLE_FMT_S16;
//输入的采样率
in_sample_rate = aCodecCtx->sample_rate;
//输入的声道布局
int in_ch_layout = aCodecCtx->channel_layout;
//输出的采样率
//out_sample_rate = 44100;
out_sample_rate = aCodecCtx->sample_rate;
audio_tgt_channels = 2; ///av_get_channel_layout_nb_channels(out_ch_layout);
out_ch_layout = av_get_default_channel_layout(audio_tgt_channels); ///AV_CH_LAYOUT_STEREO
out_ch_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
if (in_ch_layout <= 0)
{
in_ch_layout = av_get_default_channel_layout(aCodecCtx->channels);
}
swrCtx = swr_alloc_set_opts(nullptr, out_ch_layout, out_sample_fmt, out_sample_rate, in_ch_layout, in_sample_fmt, in_sample_rate, 0, nullptr);
int ret = swr_init(swrCtx);
if (ret < 0)
{
char buff[128] = { 0 };
av_strerror(ret, buff, 128);
fprintf(stderr, "Could not open resample context %s\n", buff);
swr_free(&swrCtx);
swrCtx = nullptr;
doOpenVideoFileFailed();
goto end;
}
//存储pcm数据
int out_linesize = out_sample_rate * audio_tgt_channels;
//out_linesize = av_samples_get_buffer_size(NULL, a
没有合适的资源?快使用搜索试试~ 我知道了~
基于C++ Qt+FFMPEG+SDL2写的视频播放器源代码,可以播放本地视频
共356个文件
h:215个
dll:38个
lib:22个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 2 下载量 20 浏览量
2023-09-26
15:29:37
上传
评论
收藏 94.12MB ZIP 举报
温馨提示
基于C++ Qt+FFMPEG+SDL2写的视频播放器源代码,可以播放本地视频
资源推荐
资源详情
资源评论
收起资源包目录
基于C++ Qt+FFMPEG+SDL2写的视频播放器源代码,可以播放本地视频 (356个子文件)
libavcodec.dll.a 747KB
libavcodec.dll.a 729KB
libavdevice.dll.a 412KB
libavdevice.dll.a 402KB
libavutil.dll.a 338KB
libavutil.dll.a 329KB
libavfilter.dll.a 151KB
libavfilter.dll.a 148KB
libavformat.dll.a 138KB
libavformat.dll.a 134KB
libswscale.dll.a 22KB
libswscale.dll.a 22KB
libswresample.dll.a 15KB
libswresample.dll.a 15KB
libpostproc.dll.a 7KB
libpostproc.dll.a 7KB
SDL_config.h.cmake 18KB
AVUtils.cpp 38KB
MediaShow.cpp 16KB
MainWindow.cpp 10KB
Title.cpp 3KB
MediaCtrl.cpp 2KB
InvokeUtils.cpp 2KB
Monitor.cpp 2KB
YUVFrame.cpp 1KB
MediaListWidget.cpp 903B
About.cpp 860B
Utilities.cpp 571B
WaitCondition.cpp 544B
main.cpp 455B
MediaList.cpp 269B
Setup.cpp 112B
AVPlayer.cpp 55B
avutil-56.def 12KB
avutil-56.def 12KB
avcodec-58.def 6KB
avcodec-58.def 6KB
avformat-58.def 4KB
avformat-58.def 4KB
avfilter-7.def 2KB
avfilter-7.def 2KB
swscale-5.def 756B
swscale-5.def 756B
avdevice-58.def 544B
avdevice-58.def 544B
swresample-3.def 473B
swresample-3.def 473B
postproc-55.def 223B
postproc-55.def 223B
avcodec-58.dll 43.02MB
avcodec-58.dll 43.02MB
avcodec-58.dll 43.02MB
avcodec-58.dll 30.01MB
avfilter-7.dll 7.23MB
avfilter-7.dll 7.23MB
avfilter-7.dll 7.23MB
avfilter-7.dll 6.77MB
avformat-58.dll 6.06MB
avformat-58.dll 6.06MB
avformat-58.dll 6.06MB
avformat-58.dll 5.71MB
avdevice-58.dll 2.31MB
avdevice-58.dll 2.31MB
avdevice-58.dll 2.31MB
SDL2.dll 1.54MB
SDL2.dll 1.33MB
avdevice-58.dll 1.24MB
SDL2.dll 1.13MB
SDL2.dll 1.13MB
SDL2.dll 1.13MB
SDL2.dll 982KB
avutil-56.dll 644KB
avutil-56.dll 644KB
avutil-56.dll 644KB
avutil-56.dll 640KB
swscale-5.dll 528KB
swscale-5.dll 528KB
swscale-5.dll 528KB
swscale-5.dll 504KB
swresample-3.dll 415KB
swresample-3.dll 415KB
swresample-3.dll 415KB
swresample-3.dll 305KB
postproc-55.dll 120KB
postproc-55.dll 120KB
postproc-55.dll 120KB
postproc-55.dll 111KB
MediaPlayer.vcxproj.filters 5KB
.gitignore 278B
ffmpeg.tar.gz 9.4MB
SDL2.tar.gz 1.3MB
SDL_opengl_glext.h 714KB
avcodec.h 207KB
avformat.h 115KB
SDL_opengles2_gl2ext.h 96KB
SDL_opengl.h 81KB
SDL_hints.h 76KB
SDL_egl.h 72KB
SDL_video.h 69KB
SDL_render.h 61KB
共 356 条
- 1
- 2
- 3
- 4
资源评论
- m0_749941212023-12-24资源内容详尽,对我有使用价值,谢谢资源主的分享。
- 0x55552024-03-23发现一个超赞的资源,赶紧学习起来,大家一起进步,支持!
云哲-吉吉2021
- 粉丝: 3196
- 资源: 1130
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功