日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ffmpeg推流 —— RTMP推流例程

發(fā)布時間:2024/8/1 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ffmpeg推流 —— RTMP推流例程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考:

雷霄驊 - 最簡單的基于FFmpeg的推流器(以推送RTMP為例)

nginx+rtmp配置,網(wǎng)頁播放rtmp流(實測可用)


RTMP推流例程:

#include <stdio.h> #include "libavformat/avformat.h" #include "libavutil/time.h" #include "libavutil/mathematics.h"#define RTMP_ADDR "rtmp://127.0.0.1:1935/live/1234"void fix_packet_pts(AVPacket *packet, AVRational timebase, int frame_index) {// 兩幀之間的持續(xù)時間// r_frame_rate = (AVRational) {den , num}, 與time_base結構相反AVRational in_frame_rate = {timebase.num,timebase.den,};int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(in_frame_rate); //in_stream->r_frame_ratepacket->pts = (double)(frame_index * calc_duration) / (double)(av_q2d(timebase)*AV_TIME_BASE);packet->dts = packet->pts;packet->duration = (double)calc_duration / (double)(av_q2d(timebase)*AV_TIME_BASE); }void send_rtmp(const char *file) {// 輸入AVFormatContext *ifmt_ctx = NULL;if (avformat_open_input(&ifmt_ctx, file, 0, 0) < 0) {printf("failed to open input file\n");goto _Error;}if (avformat_find_stream_info(ifmt_ctx, 0) < 0) {printf("failed to find stream info\n");goto _Error;}int video_idx = -1; video_idx = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);if (video_idx < 0) {printf("failed to find stream_index\n");goto _Error;}av_dump_format(ifmt_ctx, 0, file, 0);// 輸出AVFormatContext *ofmt_ctx = NULL;if (avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", RTMP_ADDR) < 0) {printf("failed to alloc output context\n");goto _Error;}int out_stm_idx = -1;for (int i = 0; i < ifmt_ctx->nb_streams; i++) { AVStream *in_stream = ifmt_ctx->streams[i];AVStream *out_stream = avformat_new_stream(ofmt_ctx, NULL);avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);out_stream->codecpar->codec_tag = 0;//if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) {// out_stream->codecpar->flags |= CODEC_FLAG_GLOBAL_HEADER;//}}av_dump_format(ofmt_ctx, 0, RTMP_ADDR, 1);// open output urlif (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {if (avio_open(&ofmt_ctx->pb, RTMP_ADDR, AVIO_FLAG_WRITE) < 0) {printf("failed to open output url:%s\n", RTMP_ADDR);goto _Error;}}if (avformat_write_header(ofmt_ctx, NULL) < 0) {printf("failed to write header\n");goto _Error;}int frame_index = 0;int64_t start_time = av_gettime();AVPacket *packet = av_packet_alloc();while (1) {if (av_read_frame(ifmt_ctx, packet) < 0) break;// raw h264, doesn't contain pts// 如果實際推流的是flv文件,不會執(zhí)行里面的fix_packet_ptsif (packet->pts == AV_NOPTS_VALUE) {fix_packet_pts(packet, ifmt_ctx->streams[video_idx]->time_base, frame_index); }// important delayif (packet->stream_index == video_idx) {AVRational timebase = ifmt_ctx->streams[video_idx]->time_base;AVRational timebase_q = {1, AV_TIME_BASE};int64_t pts_time = av_rescale_q(packet->pts, timebase, timebase_q);int64_t now_time = av_gettime() - start_time;if (pts_time > now_time) av_usleep(pts_time - now_time);}// rescale time baseav_packet_rescale_ts(packet, ifmt_ctx->streams[packet->stream_index]->time_base, \ofmt_ctx->streams[packet->stream_index]->time_base);packet->pos = -1;if (packet->stream_index == video_idx) {printf("send %6d video frames to output url\n", frame_index);frame_index++;}if (av_interleaved_write_frame(ofmt_ctx, packet) < 0) {printf("failed to write frame to url\n");break;}av_packet_unref(packet);}av_write_trailer(ofmt_ctx);_Error:if (ifmt_ctx) {avformat_close_input(&ifmt_ctx);}if (ofmt_ctx) {if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) avio_close(ofmt_ctx->pb);avformat_free_context(ofmt_ctx);}if (packet) av_packet_free(&packet); }int main(int argc, char const* argv[]) {send_rtmp(argv[1]); return 0; }

測試運行:


出現(xiàn)了一個警告,如下圖。大致原因就是找不到視頻的時長和文件大小信息,我們不理會也是沒有問題的。


實際用ffmpeg命令推流時也會遇到這個問題,ffmpeg -re -i ../../testvideo/chinese_partner.flv -vcodec libx264 -f flv rtmp://127.0.0.1:1935/live/1234

可以添加-flvflags no_duration_filesize 參數(shù),讓ffmpeg不要拋出duration_filesize警告。

總結

以上是生活随笔為你收集整理的ffmpeg推流 —— RTMP推流例程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。