lib/parsers/mp3_parser.rb
def parse_mpeg_frames(io)
    mpeg_frames = []
    bytes_to_read = 4

    MAX_FRAMES_TO_SCAN.times do |frame_i|
      # Read through until we can latch onto the 11 sync bits. Read in 4-byte
      # increments to save on read() calls
      data = io.read(bytes_to_read)

      # If we are at EOF - stop iterating
      break unless data && data.bytesize == bytes_to_read

      # Look for the sync pattern. It can be either the last byte being 0xFF,
      # or any of the 2 bytes in sequence being 0xFF and > 0xF0.
      four_bytes = data.unpack('C4')
      seek_jmp = sync_bytes_offset_in_4_byte_seq(four_bytes)
      if seek_jmp > 0
        io.seek(io.pos - bytes_to_read + seek_jmp)
        next
      end

      # Once we are past that stage we have latched onto a sync frame header
      sync, conf, bitrate_freq, rest = four_bytes
      frame_detail = parse_mpeg_frame_header(io.pos - bytes_to_read, sync, conf, bitrate_freq, rest)
      mpeg_frames << frame_detail

      # There might be a xing header in the first frame that contains
      # all the info we need, otherwise parse multiple frames to find the
      # accurate average bitrate
      if frame_i == 0
        frame_data_str = io.read(frame_detail.frame_length)
        io.seek(io.pos - frame_detail.frame_length)
        xing_header = attempt_xing_header(frame_data_str)
        if xing_header_usable_for_duration?(xing_header)
          return [xing_header, mpeg_frames]
        end
      end
      if frame_detail.frame_length > 1 # jump over current frame body
        io.seek(io.pos + frame_detail.frame_length - bytes_to_read)
      end
    end
    [nil, mpeg_frames]
  rescue InvalidDeepFetch # A frame was invalid - bail out since it's unlikely we can recover
    [nil, mpeg_frames]
  end
# The implementation of the MPEG frames parsing is mostly based on tinytag,
# a sweet little Python library for parsing audio metadata - do check it out
# if you have a minute. https://pypi.python.org/pypi/tinytag
The implementation of the MPEG frames parsing is mostly based on tinytag,
a sweet little Python library for parsing audio metadata - do check it out
if you have a minute.
The implementation of the MPEG frames parsing is mostly based on tinytag a sweet little Python library for parsing audio metadata - do check it out if you have a minute .
def parse_mpeg_frames(io)
    mpeg_frames = []
    bytes_to_read = 4
    MAX_FRAMES_TO_SCAN.times do |frame_i|
      data = io.read(bytes_to_read)
      break unless data && data.bytesize == bytes_to_read
      four_bytes = data.unpack('C4')
      seek_jmp = sync_bytes_offset_in_4_byte_seq(four_bytes)
      if seek_jmp > 0
        io.seek(io.pos - bytes_to_read + seek_jmp)
        next
      end
      sync, conf, bitrate_freq, rest = four_bytes
      frame_detail = parse_mpeg_frame_header(io.pos - bytes_to_read, sync, conf, bitrate_freq, rest)
      mpeg_frames << frame_detail
      if frame_i == 0
        frame_data_str = io.read(frame_detail.frame_length)
        io.seek(io.pos - frame_detail.frame_length)
        xing_header = attempt_xing_header(frame_data_str)
        if xing_header_usable_for_duration?(xing_header)
          return [xing_header, mpeg_frames]
        end
      end
      if frame_detail.frame_length > 1 
        io.seek(io.pos + frame_detail.frame_length - bytes_to_read)
      end
    end
    [nil, mpeg_frames]
  rescue InvalidDeepFetch 
    [nil, mpeg_frames]
  end
def parse_mpeg_frames ( io ) mpeg_frames = [ ] bytes_to_read = 4 MAX_FRAMES_TO_SCAN . times do | frame_i | data = io . read ( bytes_to_read ) break unless data && data . bytesize == bytes_to_read four_bytes = data . unpack ( 'C4' ) seek_jmp = sync_bytes_offset_in_4_byte_seq ( four_bytes ) if seek_jmp > 0 io . seek ( io . pos - bytes_to_read + seek_jmp ) next end sync , conf , bitrate_freq , rest = four_bytes frame_detail = parse_mpeg_frame_header ( io . pos - bytes_to_read , sync , conf , bitrate_freq , rest ) mpeg_frames << frame_detail if frame_i == 0 frame_data_str = io . read ( frame_detail . frame_length ) io . seek ( io . pos - frame_detail . frame_length ) xing_header = attempt_xing_header ( frame_data_str ) if xing_header_usable_for_duration? ( xing_header ) return [ xing_header , mpeg_frames ] end end if frame_detail . frame_length > 1 io . seek ( io . pos + frame_detail . frame_length - bytes_to_read ) end end [ nil , mpeg_frames ] rescue InvalidDeepFetch [ nil , mpeg_frames ] end
The implementation of the MPEG frames parsing is mostly based on tinytag,
a sweet little Python library for parsing audio metadata - do check it out
if you have a minute.
The implementation of the MPEG frames parsing is mostly based on tinytag a sweet little Python library for parsing audio metadata - do check it out if you have a minute .
# Read through until we can latch onto the 11 sync bits. Read in 4-byte # increments to save on read() calls # If we are at EOF - stop iterating # Look for the sync pattern. It can be either the last byte being 0xFF, # or any of the 2 bytes in sequence being 0xFF and > 0xF0. # Once we are past that stage we have latched onto a sync frame header # There might be a xing header in the first frame that contains # all the info we need, otherwise parse multiple frames to find the # accurate average bitrate # jump over current frame body # A frame was invalid - bail out since it's unlikely we can recover
io