【问题标题】:Regular expression to parse ffmpeg info解析ffmpeg信息的正则表达式
【发布时间】:2019-09-13 16:22:47
【问题描述】:

这是我的代码:

Input #0, mpegts, from 'tcp://127.0.0.1:3456':
  Duration: N/A, start: 1809.522000, bitrate: N/A
  Program 256
    Metadata:
      service_name    : AIR_CH_521_6M
      service_provider: ITE
    Stream #0:0[0x7d1]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x7d2]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels

如何从这个字符串中获取 fps、像素格式、视频编解码器、音频编解码器、输入分辨率、输出分辨率和音频通道作为数组?

根据我目前的努力,这是我所能得到的,因为我不是正则表达式专家:

/Video: ([^\r\n]*), ([^,]*), ([0-9]{1,4})x([0-9]{1,4})/iu

编辑:我尝试了另一个视频,但正则表达式不匹配。知道为什么吗?

 data :ffmpeg version 2.8.15-0ubuntu0.16.04.1 Copyright (c) 2000-2018 the FFmpeg developers
  built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.10) 20160609
  configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv

data :  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100

data :Metadata:
  Server                NGINX
  width                 1280.00
  height                720.00
  displayWidth          1280.00

data :  displayHeight         720.00
  duration              0.00
  framerate             30.00
  fps                   30.00
  videodatarate         0.00
  videocodecid          7.00
  audiodatarate         125.00
  audiocodecid          10.00

data :Input #0, live_flv, from 'rtmp://localhost/test/test':
  Metadata:
    Server          : NGINX
    displayWidth    : 1280

data :    displayHeight   : 720
    fps             : 30
    profile         :
    level           :
  Duration: 00:00:00.00, start: 11168.744000, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 30.30 fps, 30 tbr, 1k tbn, 60 tbc
    Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 128 kb/s
Output #0, mpegts, to '/dev/null':
  Metadata:
    Server          : NGINX
    displayWidth    : 1280
    displayHeight   : 720
    fps             : 30
    profile         :
    level           :
    encoder         : Lavf56.40.101
    Stream #0:0: Video: h264, yuv420p, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 30.30 fps, 30 tbr, 90k tbn, 1k tbc
    Stream #0:1: Audio: aac, 44100 Hz, stereo, 128 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help

data :frame=   54 fps=0.0 q=-1.0 size=     825kB time=00:00:02.22 bitrate=3031.6kbits/s
data :frame=   66 fps= 60 q=-1.0 size=    1004kB time=00:00:02.74 bitrate=3002.7kbits/s
data :frame=   82 fps= 50 q=-1.0 size=    1224kB time=00:00:03.34 bitrate=2998.5kbits/s

这是来自另一个文件的输入,用于正则表达式不匹配的同一命令:https://regex101.com/r/Vyq5kD/4

【问题讨论】:

  • 你能提供你想要的输出吗?
  • 如果我们能得到这样的输出就好了 .. INPUT [h264,High,yuv420p,1280x720,SAR 1:1,DAR 16:9,30.30 fps, 30 tbr, 1k tbn , 60 待定]。 [aac,LC,44100 Hz,立体声,fltp,128 kb/s] , 输出 [h264,High,yuv420p,1280x720,SAR 1:1,DAR 16:9,30.30 fps, 30 tbr, 1k tbn, 60 tbc ] . [aac,LC,44100 Hz,立体声,fltp,128 kb/s]

标签: javascript arrays regex


【解决方案1】:

我猜你可以简单地设计一些类似于,

video:\s*([a-z0-9]+)\s*\(([^)]*)\)\s*\((\[\d+\]\s*)(\[\d+\]\s*)(\[\d+\]\s*)(\[\d+\]\s*)\s*\/\s*[0-9]+x[a-z0-9]+\)\s*,\s*[a-z0-9]+\(([^)]*)\)\s*,\s*([0-9]+x[0-9]+)\s*,\s*([0-9]+)\s+([a-z]+)\s*,\s*([0-9]+)\s*([a-z]+)\s*,\s*(\d+[a-z]*)\s*([a-z]+)\s*,\s*([0-9]+)\s*([a-z]+)

Demo for Video

audio:\s*([a-z0-9]+)\s*\((\[\d+\]\s*)(\[\d+\]\s*)(\[\d+\]\s*)(\[\d+\]\s*)\s*\/\s*[0-9]+x[a-z0-9]+\)\s*,\s*([0-9]+)\s*([a-z]+)

Demo for Audio

并提取/捕获您想要的内容,并且您可能希望根据您可能拥有的输入更改边界。

Demo for Combination


如果您希望简化/修改/探索表达式,在regex101.com 的右上角面板中已对此进行了说明。如果您愿意,您还可以在 this link 中观看它如何与一些示例输入匹配。


const regex = /video:\s*([a-z0-9]+)\s*\(([^)]*)\)\s*(\((\[\d+\]\s*)(\[\d+\]\s*)(\[\d+\]\s*)(\[\d+\]\s*)\s*\/\s*[0-9]+x[a-z0-9]+\)\s*)?,\s*[a-z0-9]+\(([^)]*)\)\s*,\s*([0-9]+x[0-9]+)(\s*\[[^\]]*\])?,([^,\r\n]*),([^,\r\n]*),([^,\r\n]*),([^,\r\n]*),?([^,\r\n]*)?/gmi;
const str = `    Stream #0:0[0x7d1]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x7d2]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels

    Stream #0:0: Video: h264 (High), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 1k tbn, 60 tbc
    Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 128 kb/s
Output #0, mpegts, to '/dev/null':

    Stream #0:0: Video: h264 (High), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 30 fps, 30 tbr, 90k tbn, 1k tbc
    Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 128 kb/s
Stream mapping:`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Demo 2 for video

Demo 2 for audio

Demo 2 for Audio/Video Alternation


另一种方法是简单地定位您想要捕捉的内容,也许可以使用更简单的表达方式,例如,

(\d+)\s*fps

Demo 3


设计:

  • 您想要捕获的任何内容都将包含在捕获组() 中,例如[a-z0-9]+ for yuv420p which would become ([a-z0-9]+)

  • 我们将选择最长的字符串输入并将所有内容合并到其中,然后对于任何其他缺少值的字符串,我们将在表达式中这些缺失值的末尾添加一个 ? 以使其成为可选.

【讨论】:

  • 非常感谢您的回答。你知道我如何进一步将这些值 h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p(progressive) 拆分为 ['h264','Constrained Baseline'],[' yuv420p',progressive'],['mp3','0 个频道'] ?
  • 当我对另一个源视频运行相同的命令时,它不匹配。请在此处查看更新regex101.com/r/zJMqW8/2
  • 您最新的正则表达式运行良好,但它正在检索它找到的第一个实例。我们可以让它为每次出现的 stream# 检索相同的数据吗?
  • 我在 regex101 上使用了 generate javascript 选项,它为我提供了我需要的输出,但它提供了第一次出现 stream# 的输出。这是输出..完美匹配,第 0 组:视频:h264(高)、yuv420p(渐进式)、1280x720 [SAR 1:1 DAR 16:9]、q=2-31、30 fps、30 tbr、90k tbn、 1k tbc 找到匹配,第 1 组:h264 找到匹配,第 2 组:高找到匹配,第 8 组:渐进式找到匹配,第 9 组:1280x720 找到匹配,第 10 组:[SAR 1:1 DAR 16:9] 找到匹配,组11:q=2-31 找到匹配,第 12 组:30 fps 找到匹配,第 13 组:30 tbr
  • 匹配的多次出现也很有效,但最后一件事......它只获取视频......它与音频线不匹配
【解决方案2】:

这将为您提供单独变量和数组中的视频和音频信息。

const regex = /^(?:.|\n)*Video\:\s(\w+\d+)\s\(([\w\s]+)\).*\,\s([\w\d]+)\(([\w\s]+)\)\,\s{1}(\d+x\d+)[,\s]+(\d{0,4}\sfps)\,\s(\d+\stbr)\,\s(\d+k\stbn)\,\s(\d+\stbc)\s+.*Audio\:\s(.*)\,\s(\d+\s\w+)$/

这里是测试链接:https://regex101.com/r/0gEsnN/2

代码如下:

const regex = /^(?:.|\n)*Video\:\s(\w+\d+)\s\(([\w\s]+)\).*\,\s([\w\d]+)\(([\w\s]+)\)\,\s{1}(\d+x\d+)[,\s]+(\d{0,4}\sfps)\,\s(\d+\stbr)\,\s(\d+k\stbn)\,\s(\d+\stbc)\s+.*Audio\:\s(.*)\,\s(\d+\s\w+)$/;

const input = `Input #0, mpegts, from 'tcp://127.0.0.1:3456':
      Duration: N/A, start: 1809.522000, bitrate: N/A
      Program 256
        Metadata:
          service_name    : AIR_CH_521_6M
          service_provider: ITE
        Stream #0:0[0x7d1]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080, 30 fps, 30 tbr, 90k tbn, 60 tbc
        Stream #0:1[0x7d2]: Audio: mp3 ([4][0][0][0] / 0x0004), 0 channels`;

const resultArr = input.match(regex);

const values = resultArr.slice(1);
console.log("Values : ", values);

const [,vC1,vC2, vC3,vC4, vRes, vFps, vTbr, vTbn, vTbc, aCodec, aChannels] = resultArr;
console.log("vC1 : ", vC1);
console.log("vC2 : ", vC2);
console.log("vC3 : ", vC3);
console.log("vC4 : ", vC4);
console.log("vRes : ", vRes);
console.log("vFps : ", vFps);
console.log("vTbr : ", vTbr);
console.log("vTbn : ", vTbn);
console.log("vTbc : ", vTbc);
console.log("aCodec : ", aCodec);
console.log("aChannels : ", aChannels);

希望这会有所帮助!

【讨论】:

  • 非常感谢您的回答。你知道我如何进一步将这些值 h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p(progressive) 拆分为 ['h264','Constrained Baseline'],[' yuv420p',progressive'] ?
  • @josh 更新了答案。它现在可以在数组本身中使用。
  • 谢谢.. 现在我使用 ffmpeg 为另一个视频尝试了相同的正则表达式,但没有得到详细信息...我在这里更新了它:regex101.com/r/Vyq5kD/2
猜你喜欢
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-20
  • 2012-07-08
  • 2010-10-23
  • 2017-07-10
相关资源
最近更新 更多