【问题标题】:The .mp4 video does not play, which is created from ffmpeg library (not command line).mp4 视频不播放,它是从 ffmpeg 库(不是命令行)创建的
【发布时间】:2013-05-23 03:48:21
【问题描述】:

我使用 ffmpeg 库将帧编码为 .mp4 视频。该程序运行顺利,没有错误。但输出的 .mp4 视频无法播放。文件的属性甚至没有显示它是一个视频文件,没有任何视频流信息。

相关代码为:

const char* ouVideoFileName = "output.mp4";
AVCodecID ouCodec_id = CODEC_ID_H264;

但是如果我把它改成:

const char* ouVideoFileName = "output.avi";
AVCodecID ouCodec_id = CODEC_ID_H264;

.avi 视频可以正确播放。

.mp4 视频有什么问题?

【问题讨论】:

    标签: ffmpeg mp4 video-encoding


    【解决方案1】:

    您需要分享更多代码才能找到确切的问题。通常,一旦在输出文件名中指定了容器格式,就需要使用 av_guess_format 来获取输出格式。之后,您可以使用 av_find_encoder 建议 codec_id 你需要做这样的事情

     AVFormatContext *m_outformat = NULL;
     AVOutputFormat *outfmt = NULL;
     std::string outfile = "clip_out.mp4";
     outfmt = av_guess_format(NULL,outfile.c_str(),NULL);
    
     if(outfmt == NULL)
     {
        ret = -1;
        return ret;
     }
     else
     {
        m_outformat = avformat_alloc_context();
        if(m_outformat)
        {
           m_outformat->oformat = outfmt;
           _snprintf(m_outformat->filename, sizeof(m_outformat->filename), "%s", outfile.c_str());    
        }
        else
        {
           ret = -1;
           return ret;
        }
      }
    
        AVCodec *out_vid_codec,*out_aud_codec;
        out_vid_codec = out_aud_codec = NULL;
    
        if(outfmt->video_codec != AV_CODEC_ID_NONE && m_in_vid_strm != NULL)
        {
            out_vid_codec = avcodec_find_encoder(outfmt->video_codec);
            if(NULL == out_vid_codec)
            {
                PRINT_MSG("Could Not Find Vid Encoder")
                ret = -1;
                return ret;
            }
            else
            {
                PRINT_MSG("Found Out Vid Encoder ")
                m_out_vid_strm = avformat_new_stream(m_outformat, out_vid_codec);
                if(NULL == m_out_vid_strm)
                {
                     PRINT_MSG("Failed to Allocate Output Vid Strm ")
                     ret = -1;
                     return ret;
                }
                else
                {
                     PRINT_MSG("Allocated Video Stream ")
                     if(avcodec_copy_context(m_out_vid_strm->codec, m_informat->streams[m_in_vid_strm_idx]->codec) != 0)
                     {
                        PRINT_MSG("Failed to Copy Context ")
                        ret = -1;
                        return ret;
                     }
                     else
                     {
                        m_out_vid_strm->sample_aspect_ratio.den = m_out_vid_strm->codec->sample_aspect_ratio.den;
                        m_out_vid_strm->sample_aspect_ratio.num = m_in_vid_strm->codec->sample_aspect_ratio.num;
                        PRINT_MSG("Copied Context ")
                        m_out_vid_strm->codec->codec_id = m_in_vid_strm->codec->codec_id;
                        m_out_vid_strm->codec->time_base.num = 1;
                        m_out_vid_strm->codec->time_base.den = m_fps*(m_in_vid_strm->codec->ticks_per_frame);         
                        m_out_vid_strm->time_base.num = 1;
                        m_out_vid_strm->time_base.den = 1000;
                        m_out_vid_strm->r_frame_rate.num = m_fps;
                        m_out_vid_strm->r_frame_rate.den = 1;
                        m_out_vid_strm->avg_frame_rate.den = 1;
                        m_out_vid_strm->avg_frame_rate.num = m_fps;
                        m_out_vid_strm->duration = (m_out_end_time - m_out_start_time)*1000;
                     }
                   }
                }
          }
    
        if(outfmt->audio_codec != AV_CODEC_ID_NONE && m_in_aud_strm != NULL)
        {
            out_aud_codec = avcodec_find_encoder(outfmt->audio_codec);
            if(NULL == out_aud_codec)
            {
                PRINT_MSG("Could Not Find Out Aud Encoder ")
                ret = -1;
                return ret;
            }
            else
            {
                PRINT_MSG("Found Out Aud Encoder ")
                m_out_aud_strm = avformat_new_stream(m_outformat, out_aud_codec);
                if(NULL == m_out_aud_strm)
                {
                    PRINT_MSG("Failed to Allocate Out Vid Strm ")
                    ret = -1;
                    return ret;
                }
                else
                {
                    if(avcodec_copy_context(m_out_aud_strm->codec, m_informat->streams[m_in_aud_strm_idx]->codec) != 0)
                    {
                        PRINT_MSG("Failed to Copy Context ")
                        ret = -1;
                        return ret;
                    }
                    else
                     {
                        PRINT_MSG("Copied Context ")
                        m_out_aud_strm->codec->codec_id = m_in_aud_strm->codec->codec_id;
                        m_out_aud_strm->codec->codec_tag = 0;
                        m_out_aud_strm->pts = m_in_aud_strm->pts;
                        m_out_aud_strm->duration = m_in_aud_strm->duration;
                        m_out_aud_strm->time_base.num = m_in_aud_strm->time_base.num;
                        m_out_aud_strm->time_base.den = m_in_aud_strm->time_base.den;
    
                    }
                }
             }
          }
    
          if (!(outfmt->flags & AVFMT_NOFILE)) 
          {
            if (avio_open2(&m_outformat->pb, outfile.c_str(), AVIO_FLAG_WRITE,NULL, NULL) < 0) 
            {
                    PRINT_VAL("Could Not Open File ", outfile)
                    ret = -1;
                    return ret;
            }
          }
            /* Write the stream header, if any. */
          if (avformat_write_header(m_outformat, NULL) < 0) 
          {
                PRINT_VAL("Error Occurred While Writing Header ", outfile)
                ret = -1;
                return ret;
          }
          else
          {
                PRINT_MSG("Written Output header ")
                m_init_done = true;
          }
    

    现在你可以开始帧的编码了

    【讨论】:

    • 据我了解,如果我强制设置视频编解码器,我不需要猜测功能。
    【解决方案2】:

    我之前按照 FFmpeg 文档中的decode_encoding.c 示例。 后来我按照muxing.c的例子,现在可以了!

    【讨论】:

      猜你喜欢
      • 2016-04-28
      • 2014-07-02
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多