代码之家  ›  专栏  ›  技术社区  ›  Omar Ali

如何从ffmpeg监控进度?

  •  2
  • Omar Ali  · 技术社区  · 15 年前

    如果我使用的是Linux,那该怎么做呢?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Omar Ali    15 年前

    这就是我达成的解决方案:

    def execute_ffmpeg(cmd, progress)
      logger.debug "Running command #{cmd}"
      command = "#{cmd} 2>&1"
      progress = nil
      frames = nil
      fps = 25
      ffmpeg = IO.popen(command)
      ffmpeg.each("\r") do |line|
        if frames.nil? && line =~ /Duration:(\s.?(\d*):(\d*):(\d*\.\d*))/
          duration = $2.to_s + ":" + $3.to_s + ":" + $4.to_s
          frames = ($4.to_i + ($3.to_i * 60) + ($2.to_i * 60 * 60)) * fps
        end
        if line =~ /frame=(\s.?(\d*))/
          progress = $1.to_i / frames.to_i
          print "Progress: #{progress}"
        end
      end
    end
    
        2
  •  0
  •   Popmedic    12 年前

    谢谢你的帖子,我修改了一下。我使用的是ffmpeg版本0.10.2。以下是我的版本:

    def exec_ffmpeg src_path, dst_path
        cmd = "ffmpeg -i \"%s\" -acodec libfaac -ac 2 -ab 128k -vcodec libx264 -threads 0 \"%s\" 2>&1" %
                                [src_path, dst_path]
    
        puts "%s" % cmd.gsub(/2\>\&1$/,'')
        puts "press 'q' to quit"
        progress = nil
        dur_secs = nil
        frame_rate = nil
        frames = 0
        dur_str = '00:00:00.000'
        ostr = ''
        ffmpeg = IO.popen(cmd)
        ffmpeg.each("\r") do |line|
            if dur_secs == nil && line =~ /Duration:\s*(\d*):(\d*):(\d*\.\d*)/
                dur_str = $1.to_s + ":" + $2.to_s + ":" + $3.to_s
                dur_secs = ($3.to_f + ($2.to_i * 60).to_f + ($1.to_i * 360).to_f)
                puts "Video Duration:" + dur_str
            end
            if frame_rate == nil && line =~ /Stream.+\, (\d+\.{0,1}\d{0,3}) fps\,/
                frame_rate = $1.to_f
                frames = dur_secs * frame_rate
                puts "Total Frames: %i" % frames.to_i
                puts "Frame Rate: %.3f fps" % frame_rate
            end
            if line =~ /frame=(\s.?(\d*))/
                cframe = $1.to_i
                csecs = 0
                if line =~ /time=\s*(\d*):(\d*):(\d*\.\d*)/
                    csecs = ($3.to_f + ($2.to_i * 60).to_f + ($1.to_i * 360).to_f)
                    csecs_str = $1.to_s + ":" + $2.to_s + ":" + $3.to_s
                elsif line =~ /time=\s*(\d*\.\d*)/
                    csecs $1.to_f
                    t = Time.at(csecs).gmtime
                    csecs_str = "%0.2i:%0.2i:%0.2i.%3i" % [t.hour, t.min, t.sec, t.nsec]
                end
                if line =~ /fps=\s*(\d*)/
                    cfps = $1.to_i
                else
                    cfps = 0
                end
                if line =~ /bitrate=\s*(\d*\.\d*kbits)/
                    br = $1
                else
                    br = "???"
                end
                ostr = "  %3.2f%% ( %s ) @frame:%i fps:%i bitrate:%s" % 
                    [((csecs/dur_secs)*100), csecs_str, cframe, cfps, br]
                print ostr + ("\b" * (ostr.length + 4))
            end
        end
        print "\n"
    end