• QT+FFmpeg转存rtsp中的视频流,写入头文件失败


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 m0_61770108 2024-06-06 09:48 采纳率: 13.5% 浏览 4 首页/ 编程语言 / 已结题 QT+FFmpeg转存rtsp中的视频流,写入头文件失败 qtc++ QT+FFmpeg转存rtsp中的视频流,写入头文件失败源码如下: //打开输出文件并填充格式数据 if(avformat_alloc_output_context2(&outFmtCtx,NULL,NULL,outFileName)<0){ printf("Cannot alloc output file context.\n"); return; } //打开输出文件并填充数据 if(avio_open(&outFmtCtx->pb,outFileName,AVIO_FLAG_READ_WRITE)<0){ printf("output file open failed.\n"); return; } //在输出的mp3文件中创建一条视频流 AVStream *outAStream = avformat_new_stream(outFmtCtx,NULL);//记录视频流通道数目。存储视频流通道。 if(!outAStream){ printf("Failed allocating output stream.\n"); return ; } outAStream->time_base.den=25;//AVRational这个结构标识一个分数,num为分数,den为分母(时间的刻度) outAStream->time_base.num=1; outAStreamIndex=outAStream->index; //查找编码器 AVCodec *outCodec = const_cast (avcodec_find_decoder(codecPara->codec_id)); if(outCodec==NULL){ printf("Cannot find any encoder.\n"); return; } //从输入的h264编码器数据复制一份到输出文件的编码器中 AVCodecContext *outCodecCtx=avcodec_alloc_context3(outCodec); //申请AVCodecContext空间。需要传递一个编码器,也可以不传,但不会包含编码器。 //AVCodecParameters与AVCodecContext里的参数有很多相同的 AVCodecParameters *outCodecPara = outFmtCtx->streams[outAStream->index]->codecpar; if(avcodec_parameters_copy(outCodecPara,codecPara)<0){ printf("Cannot copy codec para.\n"); return; } if(avcodec_parameters_to_context(outCodecCtx,outCodecPara)<0){ printf("Cannot alloc codec ctx from para.\n"); return ; } outCodecCtx->bit_rate =0;//目标的码率,即采样的码率;显然,采样码率越大,视频大小越大 比特率 outCodecCtx->time_base.num=1;//下面两行:一秒钟25帧 outCodecCtx->time_base.den=15; outCodecCtx->frame_number=1;//每包一个视频帧 //打开输出文件需要的编码器 if(avcodec_open2(outCodecCtx,outCodec,NULL)<0){ printf("Cannot open output codec.\n"); return ; } printf("============Output Information=============>\n"); av_dump_format(outFmtCtx,0,outFileName,1);//输出视频信息 printf("============Output Information=============<\n"); //写入文件头 if(avformat_write_header(outFmtCtx,NULL)<0){ printf("Cannot write header to file.\n"); return ; } 报错如下: 展开全部 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    2条回答 默认 最新

    • IT工程师_二师兄 2024-06-06 09:52
      关注

      嗯,你失败的那个报错代码,还有那个报错的代码,行,你都复制出来发给我

      评论
      m0_61770108 2024-06-06 10:00

      断点调试,在这个地方报错:

      
      
      //写入文件头
          if(avformat_write_header(outFmtCtx,NULL)<0){
              printf("Cannot write header to file.\n");
              return ;
          }
      

      报错代码:

      Input #0, rtsp, from 'rtsp://.......... /Streaming/Channels/101?transportmode=unicast&profile=Profile_1':
        Metadata:
          title           : Media Presentation
        Duration: N/A, start: 0.000000, bitrate: N/A
          Stream #0:0: Video: hevc (Main), yuvj420p(pc, bt709), 2560x1440, 25 tbr, 90k tbn, 90k tbc
          Stream #0:1: Audio: pcm_alaw, 8000 Hz, 1 channels, s16, 64 kb/s
      Output #0, mp4, to '1.mp4':
          Stream #0:0: Audio: pcm_alaw, 8000 Hz, 1 channels, s16, 64 kb/s
      [mp4 @ 0000024a0624a600] Could not find tag for codec pcm_alaw in stream #0, codec not currently supported in container
      
      
      

      上下文代码:

      
      ```c++
      //打开输出文件并填充格式数据
          if(avformat_alloc_output_context2(&outFmtCtx,NULL,NULL,outFileName)<0){
              printf("Cannot alloc output file context.\n");
              return;
          }
          //打开输出文件并填充数据
          if(avio_open(&outFmtCtx->pb,outFileName,AVIO_FLAG_READ_WRITE)<0){
              printf("output file open failed.\n");
              return;
          }
          //在输出的mp3文件中创建一条视频流
          AVStream *outAStream = avformat_new_stream(outFmtCtx,NULL);//记录视频流通道数目。存储视频流通道。
          if(!outAStream){
              printf("Failed allocating output stream.\n");
              return ;
          }
          outAStream->time_base.den=25;//AVRational这个结构标识一个分数,num为分数,den为分母(时间的刻度)
          outAStream->time_base.num=1;
          outAStreamIndex=outAStream->index;
      
          //查找编码器
          AVCodec *outCodec =  const_cast (avcodec_find_decoder(codecPara->codec_id));
          if(outCodec==NULL){
              printf("Cannot find any encoder.\n");
              return;
          }
      
          //从输入的h264编码器数据复制一份到输出文件的编码器中
          AVCodecContext *outCodecCtx=avcodec_alloc_context3(outCodec); //申请AVCodecContext空间。需要传递一个编码器,也可以不传,但不会包含编码器。
          //AVCodecParameters与AVCodecContext里的参数有很多相同的
          AVCodecParameters *outCodecPara = outFmtCtx->streams[outAStream->index]->codecpar;
      
          if(avcodec_parameters_copy(outCodecPara,codecPara)<0){
              printf("Cannot copy codec para.\n");
              return;
          }
          if(avcodec_parameters_to_context(outCodecCtx,outCodecPara)<0){
              printf("Cannot alloc codec ctx from para.\n");
              return ;
          }
          outCodecCtx->bit_rate =0;//目标的码率,即采样的码率;显然,采样码率越大,视频大小越大  比特率
          outCodecCtx->time_base.num=1;//下面两行:一秒钟25帧
          outCodecCtx->time_base.den=15;
          outCodecCtx->frame_number=1;//每包一个视频帧
      
          //打开输出文件需要的编码器
          if(avcodec_open2(outCodecCtx,outCodec,NULL)<0){
              printf("Cannot open output codec.\n");
              return ;
          }
          printf("============Output Information=============>\n");
          av_dump_format(outFmtCtx,0,outFileName,1);//输出视频信息
          printf("============Output Information=============<\n");
      
          //写入文件头
          if(avformat_write_header(outFmtCtx,NULL)<0){
              printf("Cannot write header to file.\n");
              return ;
          }
      
      

      ```

      回复
    • 阿里嘎多学长 2024-06-06 09:50
      关注

      以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


      根据您提供的源码和错误信息,以下是一些可能的问题和建议的解决方案:

      1. 确保输出文件格式与期望的输出格式(mp3)相匹配

        • 您的代码中使用了avformat_alloc_output_context2函数,但没有指定输出格式。通常,您需要指定一个AVOutputFormat来确保输出文件格式与期望的格式相匹配。例如,对于MP3,您可能需要使用av_guess_format("mp3", NULL, NULL)
      2. 验证avformat_alloc_output_context2函数调用是否正确

        • 确保传递给avformat_alloc_output_context2的参数是正确的。您需要传递一个AVOutputFormat指针,如果不确定格式,可以使用NULL
      3. 检查avio_open函数调用是否成功打开输出文件

        • 确保outFileName是有效的,并且应用程序有足够的权限来写入该文件。
      4. 确保视频流被正确创建

        • 您的代码中创建了一个视频流,但是您的输出格式是MP3,这通常是音频格式。您可能需要创建一个音频流而不是视频流。
      5. 验证编码器是否被正确找到并初始化

        • 您正在使用avcodec_find_decoder,但是您应该使用avcodec_find_encoder来找到编码器,因为您正在编码数据。
      6. 检查avcodec_parameters_copyavcodec_parameters_to_context函数调用

        • 确保codecPara是有效的,并且包含了正确的编码参数。
      7. 确认avcodec_open2函数调用是否成功打开编码器

        • 确保传递给avcodec_open2的参数是正确的,并且编码器被正确初始化。
      8. 调整音频流设置

        • 根据错误信息"[mp3 @ 00000262fce1f800] Invalid audio stream. Exactly one MP3 audio stream is required.",您需要确保只创建一个音频流,并且该流的参数与MP3格式兼容。
      9. 调试avformat_write_header函数调用

        • 如果avformat_write_header失败,检查outFmtCtx是否被正确设置,并且所有必要的流和编码器参数都已经配置好。
      10. 代码实现

        • 您需要修改代码以确保创建的是音频流而不是视频流,并且使用正确的编码器和格式。以下是一个简化的示例,展示如何创建音频流并写入文件头:
      AVFormatContext *outFmtCtx = NULL;
      AVStream *outAStream = NULL;
      AVCodec *codec = NULL;
      AVCodecContext *codecCtx = NULL;
      
      // 分配格式上下文
      avformat_alloc_output_context2(&outFmtCtx, NULL, "mp3", outFileName);
      if (!outFmtCtx) {
          fprintf(stderr, "Could not deduce output format from file extension: using default.\n");
          return -1;
      }
      
      // 创建音频流
      outAStream = avformat_new_stream(outFmtCtx, NULL);
      if (!outAStream) {
          fprintf(stderr, "Failed to create audio stream.\n");
          return -1;
      }
      
      // 查找编码器
      codec = avcodec_find_encoder(AV_CODEC_ID_MP3);
      if (!codec) {
          fprintf(stderr, "Codec not found.\n");
          return -1;
      }
      
      // 分配编码器上下文
      codecCtx = avcodec_alloc_context3(codec);
      if (!codecCtx) {
          fprintf(stderr, "Could not allocate video codec context.\n");
          return -1;
      }
      
      // 设置编码器参数
      // ...
      
      // 打开编码器
      if (avcodec_open2(codecCtx, codec, NULL) < 0) {
          fprintf(stderr, "Could not open codec.\n");
          return -1;
      }
      
      // 写入文件头
      if (avformat_write_header(outFmtCtx, NULL) < 0) {
          fprintf(stderr, "Error occurred when opening output file.\n");
          return -1;
      }
      
      1. 参考资料

      请注意,这只是一个示例,您需要根据您的具体需求调整代码。希望这些建议能帮助您解决问题。

      展开全部

      评论 编辑记录
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    整车热管理「升温」,哪些厂商排名电子风扇市场份额TOP10
    UE4 蓝图宏库以及字母前缀说明
    vue-pdf多页预览异常,Rendering cancelled, page 1 Error at BaseExceptionClosure xxx
    抖音视频评论批量采集软件|视频数据提取工具
    结构型模式-代理模式
    人工智能概况笔记
    基于SSM的微博系统网站的设计与实现
    北斗导航 | 北斗/GNSS相关数据下载:IGS/IGMAS/MGEX/DCB/brdc/gamit/bernese/rinex等
    如何系列 如何玩转远程调用之OpenFegin+SpringBoot(非Cloud)
    编译报错:Manifest merge failed : Attribute application@appComponentFactory
  • 原文地址:https://ask.csdn.net/questions/8114792