前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用FFmpeg API获取flv视频时长

使用FFmpeg API获取flv视频时长

作者头像
视界音你而不同
发布2020-04-22 15:59:38
3.6K0
发布2020-04-22 15:59:38
举报

哈喽,这一篇记录一个小小的关于FFmpeg的使用,借助FFmpeg的API接口获取flv格式视频的时长。

查阅资料后,AVFormatContext中的duration字段可以获取视频时常,于是写出了如下代码:

代码语言:javascript
复制
#include <stdio.h>
#include <iostream>
extern "C" {
#include <libavformat/avformat.h>
}
#pragma comment(lib, "avformat.lib")
int main(int argc, char *argv[]) {
       if (argc < 2) {
              std::cout << "Usage: [programe] [intput_video_path/url]" << std::endl;
              return -1;
       }
       char *inputUrl = argv[1];
       AVFormatContext *fmtCtx = NULL;
       int ret;
       ret = avformat_network_init();
       if (ret < 0) {
              std::cout << "avformat_network_init failed " << std::endl;
              return -1;
       }
       fmtCtx = avformat_alloc_context();
       if (NULL == fmtCtx) {
              std::cout << "avformat_alloc_context failed " << std::endl;
              return -2;
       }
       ret = avformat_open_input(&fmtCtx, inputUrl, NULL, NULL);
       if (ret < 0) {
              std::cout << "avformat_open_input failed " << std::endl;
              return -3;
       }
       int videoIndex = -1;
       
       int nbStreams = fmtCtx->nb_streams;
       for (int i = 0; i < nbStreams; i++) {
              // fmtCtx->streams[i]->codec 新版ffmpeg已弃用
              if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                     videoIndex = i;
              }
       }
       std::cout << "----------输入流信息---------------" << std::endl;
       av_dump_format(fmtCtx, 0, inputUrl, NULL);
       long duration = fmtCtx->duration;  //微秒数
       std::cout << "duration: " << duration << std::endl;
       std::cout << "视频时常为: " << duration / 1000.0 / 1000.0 << "s" <<  std::endl;
       system("pause");
       return 0;
}

结果如下:

发现获取的视频时长为0,按照排查问题的一般思路,试试别的格式的文件是否也会有问题。尝试将文件更换为MP4文件,发现可以正常获取时长,如下图:

甚是不理解啊,经查阅资料发现,对于flv文件需要首先调用avformat_find_stream_info, 才可正常的获取视频时长,这一过程中,同时还发现另外一种获取视频时常的方式:FFmpeg对于 AVFormatContext->stream->codec的弃用(改为codecpar),修改后的代码如下:

代码语言:javascript
复制
#include <stdio.h>#include <iostream>extern "C" {#include <libavformat/avformat.h>}#pragma comment(lib, "avformat.lib")int main(int argc, char *argv[]) {       if (argc < 2) {              std::cout << "Usage: [programe] [intput_video_path/url]" << std::endl;              return -1;       }       char *inputUrl = argv[1];       AVFormatContext *fmtCtx = NULL;       int ret;       ret = avformat_network_init();       if (ret < 0) {              std::cout << "avformat_network_init failed " << std::endl;              return -1;       }       fmtCtx = avformat_alloc_context();       if (NULL == fmtCtx) {              std::cout << "avformat_alloc_context failed " << std::endl;              return -2;       }       ret = avformat_open_input(&fmtCtx, inputUrl, NULL, NULL);       if (ret < 0) {              std::cout << "avformat_open_input failed " << std::endl;              return -3;       }       ret = avformat_find_stream_info(fmtCtx, NULL);       if (ret < 0) {              std::cout << "avformat_find_stream_info failed " << std::endl;              return -4;       }       int videoIndex = -1;              int nbStreams = fmtCtx->nb_streams;       for (int i = 0; i < nbStreams; i++) {              // fmtCtx->streams[i]->codec 新版ffmpeg已弃用              if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {                     videoIndex = i;              }       }       std::cout << "----------输入流信息---------------" << std::endl;       av_dump_format(fmtCtx, 0, inputUrl, NULL);       long duration = fmtCtx->duration;  //微秒数       std::cout << "duration: " << duration << std::endl;       std::cout << "视频时常为: " << duration / 1000.0 / 1000.0 << "s" <<  std::endl;       // for flv file       int seconds = fmtCtx->streams[videoIndex]->duration * fmtCtx->streams[videoIndex]->time_base.num / fmtCtx->streams[videoIndex]->time_base.den;       std::cout << "flv file duratio: " << seconds << std::endl;       system("pause");       return 0;}

其中:另外一种获取视频时长的方式为:

代码语言:javascript
复制
int seconds = fmtCtx->streams[videoIndex]->duration * fmtCtx->streams[videoIndex]->time_base.num / fmtCtx->streams[videoIndex]->time_base.den;
       std::cout << "flv file duratio: " << seconds << std::endl;

FFmpeg弃用codec的修改为:

代码语言:javascript
复制
for (int i = 0; i < nbStreams; i++) {
              // fmtCtx->streams[i]->codec 新版ffmpeg已弃用
              if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                     videoIndex = i;
              }
       }

调用avformat_find_stream_info的部分为:

代码语言:javascript
复制
       ret = avformat_find_stream_info(fmtCtx, NULL);
       if (ret < 0) {
              std::cout << "avformat_find_stream_info failed " << std::endl;
              return -4;
       }

修改后调用结果为:

终于可以成功获取flv格式视频的时长。可以动手去试试了!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 视界音你而不同 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档