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

杭州网站开发 网站建设wordpress间文章同步

杭州网站开发 网站建设,wordpress间文章同步,沃尔玛网上商城叫什么,建设有限公司首页【FFmpeg】调用ffmpeg库实现RTMP推流 1.FFmpeg编译2.RTMP服务器搭建3.调用FFmpeg库实现RTMP推流和拉流3.1 基本框架3.2 实现代码3.3 测试3.3.1 推流3.3.2 拉流 参考#xff1a;雷霄骅博士, 调用ffmpeg库进行RTMP推流 示例工程 【FFmpeg】调用FFmpeg库实现264软编 【FFmpeg】… 【FFmpeg】调用ffmpeg库实现RTMP推流 1.FFmpeg编译2.RTMP服务器搭建3.调用FFmpeg库实现RTMP推流和拉流3.1 基本框架3.2 实现代码3.3 测试3.3.1 推流3.3.2 拉流 参考雷霄骅博士, 调用ffmpeg库进行RTMP推流 示例工程 【FFmpeg】调用FFmpeg库实现264软编 【FFmpeg】调用FFmpeg库实现264软解 1.FFmpeg编译 参考: FFmpeg在Windows下的编译 本文使用FFmpeg-7.0版本 2.RTMP服务器搭建 将本机配置成为服务器实现本地的推流和拉流操作。RTMP服务器的搭建参考RTMP服务器的搭建 RTMP是Adobe提出的一种应用层的协议用于解决多媒体数据传输流的多路复用Multiplexing和分包packetizing的问题传输传输媒体的格式为FLV因此本文推流的格式是flv格式。flv文件可以使用ffmpeg命令行从yuv文件转换而来。 3.调用FFmpeg库实现RTMP推流和拉流 3.1 基本框架 在实现时对参考博客中的部分函数进行了修改 不再使用av_register_all()函数对编解码器进行初始化增加av_log_set_level(AV_LOG_TRACE)增加日志输出信息使用本机IP127.0.0.1修改部分参数的调用因为部分变量存储的位置发生了变化修改部分函数的调用因为使用的FFmpeg版本不同将推流和拉流的部分合并用一套代码实现 在编码过程当中主要使用了如下的函数 函数名作用av_log_set_level配置输出日志级别 (AV_LOG_TRACE最详细)avformat_network_init初始化网络模块avformat_open_input打开输入文件并且将文件信息赋值给AVFormatContext保存avformat_find_stream_info根据AVFormatContext查找流信息av_dump_format将AVFormatContext中的媒体文件的信息进行格式化输出avformat_alloc_output_context2根据format_name或filename或oformat创建输出文件的AVFormatContext信息avformat_new_stream根据AVFormatContext和AVCodecContext创建新的流avcodec_parameters_copy拷贝AVCodecParametersavio_open根据url进行AVIOContext的创建与初始化这个url在推流时就是服务器地址avformat_write_header为流分配priv_data并且将流的头信息写入到输出媒体文件av_read_frame根据AVFormatContext所提供的的信息读取一帧存入AVPacketav_interleaved_write_frame以交错的方式将帧送入到媒体文件中av_packet_unref释放AVPacketav_write_trailer将流的尾部写入到输出的媒体文件中并且释放文件中的priv_dataavformat_close_input释放AVFormatContext 从使用的函数来看主要的操作流程和数据流走向大约为 初始化网络模块为RTMP传输进行准备avformat_network_init打开输入文件创建输入文件结构体并且读取输入文件信息avformat_open_input此时也会创建输入的流信息结构体根据输入文件查找流信息赋值给流信息结构体avformat_find_stream_info打印输入文件信息av_dump_format根据输出文件信息来创建输出文件结构体avformat_alloc_output_context2创建输出流avformat_new_stream将输入流的参数拷贝给输出给输出流avcodec_parameters_copy打印输出文件信息av_dump_format打开输出口准备推流avio_open写入流的头部信息avformat_write_header读取一帧信息存储到AVPacket中av_read_frame处理时间戳PTS是播放时间戳告诉播放器播放这一帧的时间DTS是解码时间戳告诉播放器解码这一帧的时间PTS通常是按照递增顺序排列的。这里雷博士认为延时很重要如果不对前后帧推流的时间进行控制帧会瞬时推送到服务器端会出现服务器无法正常接收帧的情况将帧推流av_interleaved_write_frame写入流的尾部信息av_write_trailer释放结构体信息av_packet_unref、av_write_trailer和avformat_close_input 3.2 实现代码 在调试时发现如果AVPacket这里定义如果是指针的话会出现av_read_frame第二帧读取失败的情况这里有待进一步学习。 在代码中利用bool is_sender来控制是发送还是接收发送和接收都使用同一套代码只是在时间戳部分有所区别即发送端需要计算而接收端不需要使用。不过这里的in_url和out_url还是固定的实际使用时得重新配置。 #pragma warning(disable : 4996)#include stdio.h #include stdlib.h #include string.h #include streamer.h#ifdef _WIN32 //Windows extern C { #include libavcodec/avcodec.h #include libavformat/avformat.h #include libavutil/avutil.h #include libavutil/opt.h #include libavutil/time.h #include libavutil/timestamp.h #include libavutil/mathematics.h #include libavutil/log.h }; #else //Linux... #ifdef __cplusplus extern C { #endif #include libavcodec/avcodec.h #include libavformat/avformat.h #include libavutil/avutil.h #include libavutil/opt.h #ifdef __cplusplus }; #endif #endifint streamer_internal(const char* in_url, const char* out_url, bool is_sender) {// set log level// av_log_set_level(AV_LOG_TRACE);AVOutputFormat* av_out_fmt NULL;AVFormatContext* av_in_fmt_ctx NULL;AVFormatContext* av_out_fmt_ctx NULL;AVPacket av_pkt;const char* in_filename in_url;const char* out_filename out_url;int ret 0;int i 0;int video_idx -1;int frame_idx 0;int64_t start_time 0;// bool b_sender 0;//in_filename enc_in_all.flv; // input flv file//out_filename rtmp://127.0.0.1:1935/live/stream; // output url//in_filename rtmp://127.0.0.1:1935/live/stream; // input flv file//out_filename receive.flv; // output url// av_register_all(); // 新版本ffmpeg不再使用// init networkavformat_network_init();if ((ret avformat_open_input(av_in_fmt_ctx, in_filename, 0, 0)) 0) {fprintf(stderr, Could not open input file.);goto end;}if ((ret avformat_find_stream_info(av_in_fmt_ctx, 0)) 0) {fprintf(stderr, Failed to retrive input stream information);goto end;}for (i 0; i av_in_fmt_ctx-nb_streams; i) {if (av_in_fmt_ctx-streams[i]-codecpar-codec_type AVMEDIA_TYPE_VIDEO) {video_idx i;break;}}// 将AVFormatContext结构体中媒体文件的信息进行格式化输出av_dump_format(av_in_fmt_ctx, 0, in_filename, 0);// Output// av_out_fmt_ctx是函数执行成功之后的上下文信息结构体// flv是输出格式// out_filename是输出文件ret avformat_alloc_output_context2(av_out_fmt_ctx, NULL, NULL, out_filename); // RTMP// ret avformat_alloc_output_context2(av_out_fmt_ctx, NULL, flv, out_filename); // RTMP// avformat_alloc_output_context2(av_out_fmt_ctx, NULL, mpegts, out_filename); // UDPif (ret 0) {fprintf(stderr, Could not create output context, error code:%d\n, ret);//ret AVERROR_UNKNOWN;goto end;}// av_out_fmt_ctx-oformat;for (i 0; i av_in_fmt_ctx-nb_streams; i) {AVStream* in_stream av_in_fmt_ctx-streams[i];// 为av_out_fmt_ctx创建一个新的流第二个参数video_codec没有被使用AVStream* out_stream avformat_new_stream(av_out_fmt_ctx, av_in_fmt_ctx-video_codec);//AVStream* out_stream avformat_new_stream(av_out_fmt_ctx, in_stream-codec-codec);if (!out_stream) {fprintf(stderr, Failed to allocating output stream\n);ret AVERROR_UNKNOWN;goto end;}// Copy the setting of AVCodecContext// ret avcodec_copy_context(out_stream-codecpar, in_stream-codecpar);ret avcodec_parameters_copy(out_stream-codecpar, in_stream-codecpar);if (ret 0) {fprintf(stderr, Failed to copy context from input to output stream codec context\n);goto end;}out_stream-codecpar-codec_tag 0;if (av_out_fmt_ctx-oformat-flags AVFMT_GLOBALHEADER) {// out_stream-codec-flags | CODEC_FLAG_GLOBAL_HEADER;// out_stream-event_flags | AV_CODEC_FLAG_GLOBAL_HEADER;}}// Dump format// 将AVFormatContext结构体中媒体文件的信息进行格式化输出av_dump_format(av_out_fmt_ctx, 0, out_filename, 1);// Open output URL if (!(av_out_fmt_ctx-oformat-flags AVFMT_NOFILE)) {// 打开文件ret avio_open(av_out_fmt_ctx-pb, out_filename, AVIO_FLAG_WRITE);if (ret 0) {fprintf(stderr, Could not open output URL %s, out_filename);goto end;}}// Write file headerret avformat_write_header(av_out_fmt_ctx, NULL);if (ret 0) {fprintf(stderr, Error occured when opening output URL\n);goto end;}if (is_sender) {start_time av_gettime();}while(1) {AVStream* in_stream;AVStream* out_stream;// get an AVPacket// 这里如果使用av_pkt指针的话第二帧时就会出错ret av_read_frame(av_in_fmt_ctx, av_pkt);if (ret 0) {break;}// write ptsif (av_pkt.pts AV_NOPTS_VALUE is_sender) {// write ptsAVRational time_base1 av_in_fmt_ctx-streams[video_idx]-time_base;// Duration between 2 frames (us)int64_t calc_duration (double)AV_TIME_BASE / av_q2d(av_in_fmt_ctx-streams[video_idx]-r_frame_rate);// parameters// pts是播放时间戳,告诉播放器什么时候播放这一帧视频,PTS通常是按照递增顺序排列的,以保证正确的时间顺序和播放同步// dts是解码时间戳,告诉播放器什么时候解码这一帧视频av_pkt.pts (double)(frame_idx * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE);av_pkt.dts av_pkt.pts;av_pkt.duration (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE);}// important: delayif (av_pkt.stream_index video_idx is_sender) {AVRational time_base av_in_fmt_ctx-streams[video_idx]-time_base;AVRational time_base_q { 1, AV_TIME_BASE };int64_t pts_time av_rescale_q(av_pkt.dts, time_base, time_base_q);int64_t now_time av_gettime() - start_time;if (pts_time now_time) {av_usleep(pts_time - now_time);}// av_usleep(50);}in_stream av_in_fmt_ctx-streams[av_pkt.stream_index];out_stream av_out_fmt_ctx-streams[av_pkt.stream_index];// copy packet// convert PTS/DTSav_pkt.pts av_rescale_q_rnd(av_pkt.pts, in_stream-time_base, out_stream-time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));av_pkt.dts av_rescale_q_rnd(av_pkt.dts, in_stream-time_base, out_stream-time_base, (AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));av_pkt.duration av_rescale_q(av_pkt.duration, in_stream-time_base, out_stream-time_base);av_pkt.pos -1;// print to screenif (av_pkt.stream_index video_idx) {if (is_sender) {fprintf(stdout, Send %8d video frames to output URL\n, frame_idx);}else {fprintf(stdout, Receive %8d video frames from input URL\n, frame_idx);}frame_idx;}ret av_interleaved_write_frame(av_out_fmt_ctx, av_pkt);// ret av_write_frame(av_out_fmt_ctx, av_pkt);if (ret 0) {fprintf(stderr, Error muxing packet, error code:%d\n, ret);break;}// av_packet_free(av_pkt);av_packet_unref(av_pkt);} // write file trailerav_write_trailer(av_out_fmt_ctx);end:avformat_close_input(av_in_fmt_ctx);// close output/*if (av_out_fmt_ctx !(av_out_fmt-flags AVFMT_NOFILE)) {avio_close(av_out_fmt_ctx-pb);}*//*avformat_free_context(av_out_fmt_ctx);if (ret 0 ret ! AVERROR_EOF) {fprintf(stderr, Error occured\n);return -1;}*/return 0; }int streamer() {const char* in_url rtmp://127.0.0.1:1935/live/stream; // input flv fileconst char* out_url receive.flv; // output urlbool is_sender 0;streamer_internal(in_url, out_url, is_sender);return 0; }3.3 测试 3.3.1 推流 使用代码进行推流可以访问http://localhost/stat地址查看推流的状态。 ... ...Metadata:encoder : Lavf61.3.100Duration: 00:00:40.00, start: 0.000000, bitrate: 18849 kb/sStream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1200, 25 fps, 25 tbr, 1k tbn Output #0, flv, to rtmp://127.0.0.1:1935/live/stream:Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1200, q2-31 Send 0 video frames to output URL Send 1 video frames to output URL Send 2 video frames to output URL Send 3 video frames to output URL Send 4 video frames to output URL Send 5 video frames to output URL Send 6 video frames to output URL Send 7 video frames to output URL Send 8 video frames to output URL Send 9 video frames to output URL Send 10 video frames to output URL Send 11 video frames to output URL Send 12 video frames to output URL Send 13 video frames to output URL Send 14 video frames to output URL Send 15 video frames to output URL Send 16 video frames to output URL Send 17 video frames to output URL Send 18 video frames to output URL ... ...3.3.2 拉流 拉流时需要对齐推流和拉流时的RTMP地址。如果不对齐拉流将会一直处于idel状态。 Input #0, flv, from rtmp://127.0.0.1:1935/live/stream:Metadata:|RtmpSampleAccess: trueServer : NGINX RTMP (github.com/arut/nginx-rtmp-module)displayWidth : 1920displayHeight : 1200fps : 25profile :level :Duration: 00:00:00.00, start: 59.120000, bitrate: N/AStream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1200, 25 fps, 25 tbr, 1k tbn Output #0, flv, to receive.flv:Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1200, q2-31 Receive 0 video frames from input URL Receive 1 video frames from input URL Receive 2 video frames from input URL Receive 3 video frames from input URL Receive 4 video frames from input URL Receive 5 video frames from input URL Receive 6 video frames from input URL Receive 7 video frames from input URL Receive 8 video frames from input URL Receive 9 video frames from input URL Receive 10 video frames from input URL Receive 11 video frames from input URL Receive 12 video frames from input URL另外推流和拉流也可以使用其他已有工具例如推流直接使用ffmpeg.exe拉流使用ffplay.exe或VLC Media Player CSDN: https://blog.csdn.net/weixin_42877471 Github: https://github.com/DoFulangChen/
http://www.yingshimen.cn/news/64917/

相关文章:

  • 手机网站开发模拟手机网站框架设计
  • 普通网站和营销网站有何不同怎样做网站导航栏
  • 众搜科技做百度网站即墨网站建设即墨
  • 用域名访问网站wordpress占用
  • 韩国平面设计网站泌阳网站建设
  • 网站建设前期定制物品的app有哪些
  • 网站开发外包公司有哪些部门手机网站做seo
  • 做利基网站用备案电子商务网站开发与应用论文
  • 最简单的网站开发软件广告牌设计模板
  • 域名指向另一个网站网站维护是谁做的
  • asp.net 建立网站吗wordpress浮窗播放器
  • 网络科技公司门户网站扬中人才
  • 营销型企业网站建设流程app开发软件外包
  • 网站建设及报价方案百度云网盘资源搜索
  • 开发网站合作协议怎么可以让百度快速收录视频
  • php企业网站cmswordpress插件更新推送
  • 网站在线预约模板公司做网站建设价格
  • 学校的网站怎么做的好百度seo网站在线诊断
  • 自己也可以免费轻松创建一个网站个人网站欣赏的网站
  • 网站底部导航栏怎么做宣传 网站建设方案
  • 网店美工培训教程岳阳优化公司
  • 做服装团购网站马云做网站最开始怎么盈利的
  • 余杭建设局网站网线制作实验报告总结
  • 成都鸿邑网站建设营销网站的建设与管理包括哪些事项
  • 网站要怎么运营网站开发学哪种语言
  • 提供手机自适应网站建设维护企业网站开发开题报告
  • 上海做网站 公司wordpress新页面404
  • dw网站开发无备案网站广告如何做
  • 保姆给老人做爰神马网站网站栏目模板如何选择
  • 贵阳网站开发外包磐安网站建设