怎么配合ffmpeg接口获取视频音频媒体信息

其他教程   发布日期:2023年09月08日   浏览次数:535

今天小编给大家分享一下怎么配合ffmpeg接口获取视频音频媒体信息的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

一、前言

做音视频开发过程中,经常需要获取媒体文件的详细信息。

比如:获取视频文件的总时间、帧率、尺寸、码率等等信息。 获取音频文件的的总时间、帧率、码率,声道等信息。 这篇文章贴出2个我封装好的函数,直接调用就能获取媒体信息返回,cop过去就能使用,非常方便。

如果要获取详细信息,可以使用

  1. ffprobe
实现,也可以调用ffmpeg函数直接打开视频解析获取。

下面会演示两种方式,一种直接调用

  1. ffprobe.exe
实现,一种是调用ffmpeg函数直接打开视频解析获取。

如果调用

  1. ffprobe.exe
实现,可以编译ffmpeg源码,以静态方式编译
  1. ffprobe.exe
,这样调用起来比较方便,不需要带任何的依赖库。

下面 调用

  1. ffprobe.exe
以JSON形式输出媒体文件的详细信息。
  1. ffprobe -v quiet -of json -i D:/123.mp4 -show_streams

执行之后直接通过JSON格式输出:

  1. C:Users11266>ffprobe -v quiet -of json -i D:/123.mp4 -show_streams
  2. {
  3. "streams": [
  4. {
  5. "index": 0,
  6. "codec_name": "aac",
  7. "codec_long_name": "AAC (Advanced Audio Coding)",
  8. "profile": "LC",
  9. "codec_type": "audio",
  10. "codec_time_base": "1/88200",
  11. "codec_tag_string": "mp4a",
  12. "codec_tag": "0x6134706d",
  13. "sample_fmt": "fltp",
  14. "sample_rate": "88200",
  15. "channels": 2,
  16. "channel_layout": "stereo",
  17. "bits_per_sample": 0,
  18. "r_frame_rate": "0/0",
  19. "avg_frame_rate": "0/0",
  20. "time_base": "1/44100",
  21. "start_pts": 0,
  22. "start_time": "0.000000",
  23. "duration_ts": 4141046,
  24. "duration": "93.901270",
  25. "bit_rate": "127948",
  26. "max_bit_rate": "132760",
  27. "nb_frames": "4045",
  28. "disposition": {
  29. "default": 1,
  30. "dub": 0,
  31. "original": 0,
  32. "comment": 0,
  33. "lyrics": 0,
  34. "karaoke": 0,
  35. "forced": 0,
  36. "hearing_impaired": 0,
  37. "visual_impaired": 0,
  38. "clean_effects": 0,
  39. "attached_pic": 0,
  40. "timed_thumbnails": 0
  41. },
  42. "tags": {
  43. "creation_time": "2015-04-30T02:43:22.000000Z",
  44. "language": "und",
  45. "handler_name": "GPAC ISO Audio Handler"
  46. }
  47. },
  48. {
  49. "index": 1,
  50. "codec_name": "h464",
  51. "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
  52. "profile": "Main",
  53. "codec_type": "video",
  54. "codec_time_base": "2349/70450",
  55. "codec_tag_string": "avc1",
  56. "codec_tag": "0x31637661",
  57. "width": 1280,
  58. "height": 720,
  59. "coded_width": 1280,
  60. "coded_height": 720,
  61. "has_b_frames": 0,
  62. "sample_aspect_ratio": "1:1",
  63. "display_aspect_ratio": "16:9",
  64. "pix_fmt": "yuv420p",
  65. "level": 51,
  66. "chroma_location": "left",
  67. "refs": 1,
  68. "is_avc": "true",
  69. "nal_length_size": "4",
  70. "r_frame_rate": "25/1",
  71. "avg_frame_rate": "35225/2349",
  72. "time_base": "1/30000",
  73. "start_pts": 0,
  74. "start_time": "0.000000",
  75. "duration_ts": 2816400,
  76. "duration": "93.880000",
  77. "bit_rate": "582474",
  78. "bits_per_raw_sample": "8",
  79. "nb_frames": "1409",
  80. "disposition": {
  81. "default": 1,
  82. "dub": 0,
  83. "original": 0,
  84. "comment": 0,
  85. "lyrics": 0,
  86. "karaoke": 0,
  87. "forced": 0,
  88. "hearing_impaired": 0,
  89. "visual_impaired": 0,
  90. "clean_effects": 0,
  91. "attached_pic": 0,
  92. "timed_thumbnails": 0
  93. },
  94. "tags": {
  95. "creation_time": "2015-04-30T02:43:23.000000Z",
  96. "language": "und",
  97. "handler_name": "GPAC ISO Video Handler"
  98. }
  99. }
  100. ]
  101. }

如果只是想要得到 媒体的总时长、尺寸信息,那么执行下面命令即可:

  1. C:Users11266>ffprobe -i D:/123.mp4
  2. ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
  3. built with gcc 9.2.1 (GCC) 20200122
  4. configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
  5. libavutil 56. 31.100 / 56. 31.100
  6. libavcodec 58. 54.100 / 58. 54.100
  7. libavformat 58. 29.100 / 58. 29.100
  8. libavdevice 58. 8.100 / 58. 8.100
  9. libavfilter 7. 57.100 / 7. 57.100
  10. libswscale 5. 5.100 / 5. 5.100
  11. libswresample 3. 5.100 / 3. 5.100
  12. libpostproc 55. 5.100 / 55. 5.100
  13. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'D:/123.mp4':
  14. Metadata:
  15. major_brand : mp42
  16. minor_version : 0
  17. compatible_brands: mp42isom
  18. creation_time : 2015-04-30T02:43:22.000000Z
  19. Duration: 00:01:33.90, start: 0.000000, bitrate: 715 kb/s
  20. Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 88200 Hz, stereo, fltp, 127 kb/s (default)
  21. Metadata:
  22. creation_time : 2015-04-30T02:43:22.000000Z
  23. handler_name : GPAC ISO Audio Handler
  24. Stream #0:1(und): Video: h464 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 582 kb/s, 15 fps, 25 tbr, 30k tbn, 20000k tbc (default)
  25. Metadata:
  26. creation_time : 2015-04-30T02:43:23.000000Z
  27. handler_name : GPAC ISO Video Handler

二、调用ffprobe获取媒体信息

下面利用Qt编写代码调用

  1. ffprobe
可执行文件,解析媒体信息输出。

下面封装了2个函数,完整媒体信息的解析返回。

【1】获取尺寸和时长

  1. //媒体信息
  2. struct MEDIA_INFO
  3. {
  4. int width; //宽度
  5. int height; //高度
  6. qint64 duration;//视频总时长--毫秒
  7. };
  8. //获取视频的尺寸和总时间信息
  9. struct MEDIA_INFO GetVideo_SizeInfo(QString file)
  10. {
  11. int w, h;
  12. struct MEDIA_INFO info = {0,0,0};
  13. //拼接ffmpge的路径
  14. QString cmd = QString("%1 -i "%2"").arg(FFPROBE_NAME).arg(file);
  15. QProcess process;
  16. process.setProcessChannelMode(QProcess::MergedChannels);
  17. process.start(cmd.toUtf8());
  18. process.waitForFinished();
  19. process.waitForReadyRead();
  20. //qDebug() << "cmd:" << cmd;
  21. if (process.exitCode() == 0)
  22. {
  23. log_printf(QString("Run Success"));
  24. QString qba = process.readAll();
  25. QByteArray utf8_str = qba.toUtf8();
  26. // Match duration
  27. QRegularExpression reDuration("Duration: (d{2}:d{2}:d{2}.d{2})");
  28. QRegularExpressionMatch matchDuration = reDuration.match(utf8_str);
  29. if (matchDuration.hasMatch())
  30. {
  31. QString duration = matchDuration.captured(1);
  32. // "00:06:37.15"
  33. qDebug() << "视频总时间:" << duration;
  34. int hour=duration.section(":", 0, 0).toInt();
  35. int minute = duration.section(":", 1, 1).toInt();
  36. int second = duration.section(":", 2, 3).section(".",0,0).toInt();
  37. int ms = duration.section(":", 2, 3).section(".", 1, 1).toInt();
  38. info.duration= hour * 60 * 60 *1000 + minute * 60 *1000 + second*1000 + ms;
  39. }
  40. else
  41. {
  42. qDebug() << "No duration match found.";
  43. }
  44. // Match resolution
  45. QRegularExpression reResolution("d{3,4}xd{3,4}");
  46. QRegularExpressionMatch matchResolution = reResolution.match(utf8_str);
  47. if (matchResolution.hasMatch())
  48. {
  49. QString resolution = matchResolution.captured(0);
  50. //qDebug() << "视频尺寸:" << resolution;
  51. //qDebug() << "视频尺寸--w:" << resolution.section("x", 0, 0);
  52. //qDebug() << "视频尺寸--h:" << resolution.section("x", 1, 1);
  53. info.width = resolution.section("x", 0, 0).toInt();
  54. info.height = resolution.section("x", 1, 1).toInt();
  55. }
  56. else
  57. {
  58. qDebug() << "No resolution match found.";
  59. }
  60. }
  61. else
  62. {
  63. log_printf(QString("Run ERROR"));
  64. return info;
  65. }
  66. return info;
  67. }

【2】获取媒体详细并解析出来

  1. // 定义用于存储解析结果的结构体
  2. struct Stream {
  3. int index;
  4. QString codecName;
  5. QString codecLongName;
  6. QString profile;
  7. QString codecType;
  8. QString codecTimeBase;
  9. QString codecTagString;
  10. QString codecTag;
  11. int width;
  12. int height;
  13. int codedWidth;
  14. int codedHeight;
  15. bool hasBFrames;
  16. QString pixFmt;
  17. int level;
  18. QString colorRange;
  19. QString colorSpace;
  20. QString colorTransfer;
  21. QString colorPrimaries;
  22. QString chromaLocation;
  23. int refs;
  24. bool isAVC;
  25. int nalLengthSize;
  26. QString rFrameRate;
  27. QString avgFrameRate;
  28. QString timeBase;
  29. qint64 startPts;
  30. QString startTime;
  31. qint64 durationTs;
  32. QString duration;
  33. int bitRate;
  34. int bitsPerRawSample;
  35. int nbFrames;
  36. struct Disposition {
  37. int defaultValue;
  38. int dub;
  39. int original;
  40. int comment;
  41. int lyrics;
  42. int karaoke;
  43. int forced;
  44. int hearingImpaired;
  45. int visualImpaired;
  46. int cleanEffects;
  47. int attachedPic;
  48. int timedThumbnails;
  49. } disposition;
  50. struct Tags {
  51. QString language;
  52. QString handlerName;
  53. } tags;
  54. };
  55. //解析存放媒体信息的JSON结构
  56. QVector<Stream> DecodeMediaInfo(QString mediafile)
  57. {
  58. QByteArray byte_data=mediafile.toUtf8();
  59. //获取媒体信息
  60. QByteArray jsonStr = GetMediaInfo(byte_data.data());
  61. // 将json字符串转换为json文档对象
  62. QJsonDocument doc = QJsonDocument::fromJson(jsonStr);
  63. // 获取顶层json对象
  64. QJsonObject topLevelObj = doc.object();
  65. // 获取streams数组
  66. QJsonArray streamsArray = topLevelObj.value("streams").toArray();
  67. // 遍历streams数组,将每个元素转换为Stream结构体
  68. QVector<Stream> streamVec;
  69. for (const QJsonValue & streamValue : streamsArray) {
  70. QJsonObject streamObj = streamValue.toObject();
  71. // 创建新的Stream实例,并设置属性值
  72. Stream stream;
  73. stream.index = streamObj.value("index").toInt();
  74. stream.codecName = streamObj.value("codec_name").toString();
  75. stream.codecLongName = streamObj.value("codec_long_name").toString();
  76. stream.profile = streamObj.value("profile").toString();
  77. stream.codecType = streamObj.value("codec_type").toString();
  78. stream.codecTimeBase = streamObj.value("codec_time_base").toString();
  79. stream.codecTagString = streamObj.value("codec_tag_string").toString();
  80. stream.codecTag = streamObj.value("codec_tag").toString();
  81. stream.width = streamObj.value("width").toInt();
  82. stream.height = streamObj.value("height").toInt();
  83. stream.codedWidth = streamObj.value("coded_width").toInt();
  84. stream.codedHeight = streamObj.value("coded_height").toInt();
  85. stream.hasBFrames = streamObj.value("has_b_frames").toBool();
  86. stream.pixFmt = streamObj.value("pix_fmt").toString();
  87. stream.level = streamObj.value("level").toInt();
  88. stream.colorRange = streamObj.value("color_range").toString();
  89. stream.colorSpace = streamObj.value("color_space").toString();
  90. stream.colorTransfer = streamObj.value("color_transfer").toString();
  91. stream.colorPrimaries = streamObj.value("color_primaries").toString();
  92. stream.chromaLocation = streamObj.value("chroma_location").toString();
  93. stream.refs = streamObj.value("refs").toInt();
  94. stream.isAVC = streamObj.value("is_avc").toBool();
  95. stream.nalLengthSize = streamObj.value("nal_length_size").toInt();
  96. stream.rFrameRate = streamObj.value("r_frame_rate").toString();
  97. stream.avgFrameRate = streamObj.value("avg_frame_rate").toString();
  98. stream.timeBase = streamObj.value("time_base").toString();
  99. stream.startPts = streamObj.value("start_pts").toInt();
  100. stream.startTime = streamObj.value("start_time").toString();
  101. stream.durationTs = streamObj.value("duration_ts").toInt();
  102. stream.duration = streamObj.value("duration").toString();
  103. stream.bitRate = streamObj.value("bit_rate").toInt();
  104. stream.bitsPerRawSample = streamObj.value("bits_per_raw_sample").toInt();
  105. stream.nbFrames = streamObj.value("nb_frames").toInt();
  106. // 解析disposition对象
  107. QJsonObject dispositionObj = streamObj.value("disposition").toObject();
  108. stream.disposition.defaultValue = dispositionObj.value("default").toInt();
  109. stream.disposition.dub = dispositionObj.value("dub").toInt();
  110. stream.disposition.original = dispositionObj.value("original").toInt();
  111. stream.disposition.comment = dispositionObj.value("comment").toInt();
  112. stream.disposition.lyrics = dispositionObj.value("lyrics").toInt();
  113. stream.disposition.karaoke = dispositionObj.value("karaoke").toInt();
  114. stream.disposition.forced = dispositionObj.value("forced").toInt();
  115. stream.disposition.hearingImpaired = dispositionObj.value("hearing_impaired").toInt();
  116. stream.disposition.visualImpaired = dispositionObj.value("visual_impaired").toInt();
  117. stream.disposition.cleanEffects = dispositionObj.value("clean_effects").toInt();
  118. stream.disposition.attachedPic = dispositionObj.value("attached_pic").toInt();
  119. stream.disposition.timedThumbnails = dispositionObj.value("timed_thumbnails").toInt();
  120. // 解析tags对象
  121. QJsonObject tagsObj = streamObj.value("tags").toObject();
  122. stream.tags.language = tagsObj.value("language").toString();
  123. stream.tags.handlerName = tagsObj.value("handler_name").toString();
  124. // 将Stream实例添加到vector中
  125. streamVec.append(stream);
  126. // 打印解析结果
  127. for (const Stream & stream : streamVec) {
  128. qDebug() << "Index:" << stream.index
  129. << "Codec Name:" << stream.codecName
  130. << "Codec Long Name:" << stream.codecLongName
  131. << "Profile:" << stream.profile
  132. << "Codec Type:" << stream.codecType
  133. << "Codec Time Base:" << stream.codecTimeBase
  134. << "Codec Tag String:" << stream.codecTagString
  135. << "Codec Tag:" << stream.codecTag
  136. << "Width:" << stream.width
  137. << "Height:" << stream.height
  138. << "Coded Width:" << stream.codedWidth
  139. << "Coded Height:" << stream.codedHeight
  140. << "Has B Frames:" << stream.hasBFrames
  141. << "Pixel Format:" << stream.pixFmt
  142. << "Level:" << stream.level
  143. << "Color Range:" << stream.colorRange
  144. << "Color Space:" << stream.colorSpace
  145. << "Color Transfer:" << stream.colorTransfer
  146. << "Color Primaries:" << stream.colorPrimaries
  147. << "Chroma Location:" << stream.chromaLocation
  148. << "Refs:" << stream.refs
  149. << "Is AVC:" << stream.isAVC
  150. << "NAL Length Size:" << stream.nalLengthSize
  151. << "R Frame Rate:" << stream.rFrameRate
  152. << "Avg Frame Rate:" << stream.avgFrameRate
  153. << "Time Base:" << stream.timeBase
  154. << "Start PTS:" << stream.startPts
  155. << "Start Time:" << stream.startTime
  156. << "Duration TS:" << stream.durationTs
  157. << "Duration:" << stream.duration
  158. << "Bitrate:" << stream.bitRate
  159. << "Bits per Raw Sample:" << stream.bitsPerRawSample
  160. << "Number of Frames:" << stream.nbFrames
  161. << "Disposition Default Value:" << stream.disposition.defaultValue
  162. << "Disposition Dub:" << stream.disposition.dub
  163. << "Disposition Original:" << stream.disposition.original
  164. << "Disposition Comment:" << stream.disposition.comment
  165. << "Disposition Lyrics:" <&

以上就是怎么配合ffmpeg接口获取视频音频媒体信息的详细内容,更多关于怎么配合ffmpeg接口获取视频音频媒体信息的资料请关注九品源码其它相关文章!