当前位置: 首页 > news >正文

织梦技术个人网站模板下载做电子书网站 赚钱

织梦技术个人网站模板下载,做电子书网站 赚钱,在线做任务的网站,网站制作优化FFmpeg 是音视频开发领域的“瑞士军刀”,其强大的功能不仅体现在命令行上,更在于其丰富的 libav 系列库。本文将带领大家利用 FFmpeg 的核心库,从零开始用 C/C 实现一个简易的视频播放器。 内容参考自 GitHub 项目:awesome_audio_…

FFmpeg 是音视频开发领域的“瑞士军刀”,其强大的功能不仅体现在命令行上,更在于其丰富的 libav 系列库。本文将带领大家利用 FFmpeg 的核心库,从零开始用 C/C++ 实现一个简易的视频播放器

内容参考自 GitHub 项目:awesome_audio_video_learning

完成本教程后,你将对播放器的基本工作原理、多线程协同以及音视频同步有更深入的理解。


项目环境准备

本文所有代码基于 Linux 环境,需要安装 FFmpeg 及其开发库。

  • FFmpeg 开发库libavformatlibavcodeclibavutil 等。
  • SDL2 库:用于窗口创建、事件处理和视频渲染。

在 Ubuntu 系统上,可以通过以下命令安装:

sudo apt update
sudo apt install build-essential libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libsdl2-dev

播放器核心流程解析

一个视频播放器可以抽象为以下几个核心步骤:

1. 解封装(Demuxing):从视频文件中读取封装好的数据包(AVPacket),并将其分发给不同的流(音频流、视频流)。
2. 解码(Decoding):将数据包中的编码数据解码为原始的音视频帧(AVFrame)。
3. 音视频同步:确保音频和视频的播放时间点一致,避免音画不同步。
4. 渲染(Rendering):将解码后的视频帧显示到屏幕上,将音频帧送入声卡播放。

我们将使用多线程来并行处理这些任务,以保证流畅播放。

关键代码实现

下面,我们将逐步构建播放器的主要逻辑。

1. 初始化 FFmpeg 和 SDL2

在开始前,需要初始化 FFmpeg 的所有组件,并创建 SDL2 窗口。

#include <iostream>
#include <SDL2/SDL.h>extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}// 全局变量和初始化函数
SDL_Window *window = nullptr;
SDL_Renderer *renderer = nullptr;
SDL_Texture *texture = nullptr;
AVFormatContext *fmt_ctx = nullptr;
AVCodecContext *video_codec_ctx = nullptr;
int video_stream_idx = -1;void init() {avformat_network_init(); // 初始化网络if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {std::cerr << "SDL_Init 失败: " << SDL_GetError() << std::endl;exit(1);}
}
2. 解封装与流信息获取

使用 avformat_open_input() 打开视频文件,并使用 avformat_find_stream_info() 读取流信息。

bool open_media(const char* filename) {if (avformat_open_input(&fmt_ctx, filename, nullptr, nullptr) < 0) {std::cerr << "无法打开文件: " << filename << std::endl;return false;}if (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {std::cerr << "无法找到流信息" << std::endl;return false;}// 找到视频流video_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);if (video_stream_idx < 0) {std::cerr << "无法找到视频流" << std::endl;return false;}// 找到解码器并打开AVCodec *codec = avcodec_find_decoder(fmt_ctx->streams[video_stream_idx]->codecpar->codec_id);if (!codec) {std::cerr << "找不到解码器" << std::endl;return false;}video_codec_ctx = avcodec_alloc_context3(codec);avcodec_parameters_to_context(video_codec_ctx, fmt_ctx->streams[video_stream_idx]->codecpar);if (avcodec_open2(video_codec_ctx, codec, nullptr) < 0) {std::cerr << "无法打开解码器" << std::endl;return false;}return true;
}
3. 解码与渲染循环

这是播放器的核心循环。我们将在主线程中进行解封装和解码,并利用 SDL2 进行渲染。

int main(int argc, char* argv[]) {if (argc < 2) {std::cerr << "用法: " << argv[0] << " <视频文件>" << std::endl;return -1;}init();if (!open_media(argv[1])) {return -1;}// 创建SDL窗口和纹理window = SDL_CreateWindow("FFmpeg Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,video_codec_ctx->width, video_codec_ctx->height, SDL_WINDOW_SHOWN);renderer = SDL_CreateRenderer(window, -1, 0);texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING,video_codec_ctx->width, video_codec_ctx->height);AVPacket *packet = av_packet_alloc();AVFrame *frame = av_frame_alloc();SwsContext *sws_ctx = sws_getContext(video_codec_ctx->width, video_codec_ctx->height, video_codec_ctx->pix_fmt,video_codec_ctx->width, video_codec_ctx->height, AV_PIX_FMT_YUV420P,SWS_BILINEAR, nullptr, nullptr, nullptr);// 主循环while (av_read_frame(fmt_ctx, packet) >= 0) {if (packet->stream_index == video_stream_idx) {avcodec_send_packet(video_codec_ctx, packet);int ret = avcodec_receive_frame(video_codec_ctx, frame);if (ret == 0) {// 解码成功,进行渲染SDL_Event event;while (SDL_PollEvent(&event)) {if (event.type == SDL_QUIT) {// ... 退出逻辑}}// 将解码后的YUV帧转换为SDL可渲染的YV12格式uint8_t *pixels[4];int pitch[4];SDL_LockTexture(texture, nullptr, (void**)pixels, pitch);sws_scale(sws_ctx, (uint8_t const * const *)frame->data, frame->linesize, 0, frame->height, pixels, pitch);SDL_UnlockTexture(texture);// 渲染到屏幕SDL_RenderClear(renderer);SDL_RenderCopy(renderer, texture, nullptr, nullptr);SDL_RenderPresent(renderer);}}av_packet_unref(packet);}// 释放资源sws_freeContext(sws_ctx);av_frame_free(&frame);av_packet_free(&packet);avcodec_close(video_codec_ctx);avformat_close_input(&fmt_ctx);SDL_Quit();return 0;
}

总结与展望

本文实现了一个最简单的视频播放器,它能够:

  • 打开一个视频文件。
  • 读取视频流,找到正确的解码器。
  • 循环读取数据包并解码为帧。
  • 使用 SDL2 渲染视频帧。

当然,这个播放器还有许多可以完善的地方,例如:

1. 多线程:将解封装、解码和渲染放入不同的线程,以实现真正的并行处理。
2. 音视频同步:加入音频流处理,并使用时间戳(PTS)进行音画同步。
3. 优化:实现播放控制(暂停、快进)、缓冲区管理和错误处理。

想要继续深入学习音视频开发的同学,可以去 GitHub 里面查看这个项目,awesome_audio_video_learning,对音视频开发有个清晰的认知后,你将能构建功能更强大、性能更优越的音视频应用。

http://www.dtcms.com/a/576715.html

相关文章:

  • 上海网站改版哪家好游戏开奖网站建设
  • 南充网站网站建设江门关键词排名工具
  • 网站设计论文的参考文献女生做交互设计师好吗
  • 天津市城市建设档案馆网站WordPress 软件 模板
  • 做写手一般上什么网站企业网络基础建设
  • akm建站系统旅游房地产网站建设
  • 池州市建设厅官方网站福州网站建设出格网络
  • logo设计网站参考山东省建设建设协会网站
  • 网站开发人员的职业要求网站建设银川
  • 做家常便饭网站万能浏览器网页版
  • php 网站做网络推广要做网站吗
  • 广州做网站哪个公司做得好金溪网站建设推广
  • 网站模板购买 优帮云中国网站优化哪家好
  • 网站开发后端用什么花儿直播免费视频观看
  • 网站空间租用价格西安seo霸屏
  • yy直播是个什么样的平台seo黑帽排名
  • 网站备案归属地wordpress摘要添加省略号
  • 网站cms系统 开源框架做网站 seo
  • 柳州网站制作工作室wordpress rest图片
  • 广告设计接单网站婚庆公司创业计划书
  • 仿一个网站眉山做网站的公司
  • 网站开发php还是jsp全屋装修公司
  • 做网站百度收费吗网站建设 海南
  • 企业网站建设策划书怎么写做360网站优化快速
  • 商家入驻网站建设生产管理系统免费版
  • asp.net 网站开发项目南阳seo网站价格
  • 长治建设网站公司丰镇市网站
  • 自主建站羊肉口报关做网站
  • 大数据精准获客平台东莞百度seo排名
  • 简单网站开发项目实例大兴专业网站开发公司