Created
February 3, 2018 03:59
-
-
Save peterc/d4446563904bcae8796b282ab9fdaee9 to your computer and use it in GitHub Desktop.
Quickly get the duration of a remote MP3 without fetching the whole thing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'uri' | |
require 'net/http' | |
require 'mp3info' | |
# This works, but is flawed and needs work. | |
# Why? An ID3v2 tag is not always going to | |
# be within the first 8K of a file! It can | |
# be up to 256MB in length apparently.. so | |
# we need to flexibly scale. But this works | |
# 99% of the time.. | |
def get_mp3_length(url) | |
uri = URI(url) | |
http = Net::HTTP.new(uri.host, uri.port) | |
# Make a request for only the first 8K of the MP3 | |
request = Net::HTTP::Get.new(uri.path) | |
request['Range'] = 'bytes=0-8192' | |
response = http.request(request) | |
# Grab out the full length of the remote file | |
bytes = response.to_hash['content-range'].first[/0-\d+\/(\d+)/, 1].to_i | |
# Open the MP3 chunk we have and get the bitrate info | |
mp3 = Mp3Info.open(StringIO.new(response.body)) | |
bitrate = mp3.bitrate * 1000 / 8 | |
mp3.close | |
# File size divided by bitrate equals approximate length | |
# Obviously, VBR can throw things off slightly | |
bytes.to_f / bitrate | |
end | |
puts get_mp3_length(ARGV.first) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hmm, seems this only works with straightforward setups, and not servers going heavy on the chunking..