在 Ruby/Rails 中读取远程 MP3 文件的 ID3 标签?

2023-11-26

使用 Ruby,如何解析远程 mp3 文件的 ID3 标签而不将整个文件下载到磁盘?

这个问题已经被问到Java and 银光,但没有红宝石。

Edit:查看 Java 答案,似乎可以(HTTP 支持)仅下载文件的尾部,即标签所在的位置。这可以在 Ruby 中完成吗?


您使用的是哪个 Ruby 版本?

您想读取哪个 ID3 标签版本?

ID3v1 标签位于文件末尾,最后 128 个字节中。使用 Net::HTTP 似乎不可能向前查找文件末尾并仅读取最后 N 个字节。如果你尝试这样做,使用headers = {"Range" => "bytes=128-"},它似乎总是下载完整的文件。resp.body.size => file-size。但损失不大,因为ID3 版本 1 目前已经过时了因为它的限制,例如固定长度格式,只能是 ASCII 文本,...)。 iTunes 使用 ID3 版本 2.2.0。

ID3v2 标签位于文件的开头 - 为了支持流式传输 - 您可以通过 HTTP 协议 >= 1.1 下载 MP3 文件的初始部分,其中包含 ID3v2 标头

简短的回答:

require 'net/http'
require 'uri'
require 'id3'    # id3 RUby library
require 'hexdump'


file_url = 'http://example.com/filename.mp3'
uri = URI(file_url)

size = 1000   # ID3v2 tags can be considerably larger, because of embedded album pictures

Net::HTTP.version_1_2  # make sure we use higher HTTP protocol version than 1.0
http = Net::HTTP.new(uri.host, uri.port)

resp = http.get( file_url , {'Range' => "bytes=0-#{size}"} )
# should check the response status codes here.. 

if resp.body =~ /^ID3/   # we most likely only read a small portion of the ID3v2 tag..
   # file has ID3v2 tag

   puts resp.body.hexdump

   tag2 = ID3::Tag2.new
   tag2.read_from_buffer( resp.body )
   @id3_tag_size = tag2.ID3v2tag_size   # that's the size of the whole ID3v2 tag
                                        # we should now re-fetch the tag with the correct / known size
   # ...
end

e.g.:

 index       0 1 2 3  4 5 6 7  8 9 A B  C D E F

00000000    ["49443302"] ["00000000"] ["11015454"] ["3200000d"]    ID3.......TT2...
00000010    ["004b6167"] ["75796120"] ["48696d65"] ["00545031"]    .Kaguya Hime.TP1
00000020    ["00000e00"] ["4a756e6f"] ["20726561"] ["63746f72"]    ....Juno reactor
00000030    ["0054414c"] ["00001100"] ["4269626c"] ["65206f66"]    .TAL....Bible of
00000040    ["20447265"] ["616d7300"] ["54524b00"] ["00050036"]     Dreams.TRK....6
00000050    ["2f390054"] ["59450000"] ["06003139"] ["39370054"]    /9.TYE....1997.T
00000060    ["434f0000"] ["1300456c"] ["65637472"] ["6f6e6963"]    CO....Electronic
00000070    ["612f4461"] ["6e636500"] ["54454e00"] ["000d0069"]    a/Dance.TEN....i
00000080    ["54756e65"] ["73207632"] ["2e300043"] ["4f4d0000"]    Tunes v2.0.COM..
00000090    ["3e00656e"] ["67695475"] ["6e65735f"] ["43444442"]    >.engiTunes_CDDB
000000a0    ["5f494473"] ["00392b36"] ["34374334"] ["36373436"]    _IDs.9+647C46746
000000b0    ["38413234"] ["38313733"] ["41344132"] ["30334544"]    8A248173A4A203ED
000000c0    ["32323034"] ["4341422b"] ["31363333"] ["39390000"]    2204CAB+163399..
000000d0    ["00000000"] ["00000000"] ["00000000"] ["00000000"]    ................

长答案看起来像这样:(您需要 id3 库版本 1.0.0_pre 或更高版本)

require 'net/http'
require 'uri'
require 'id3'    # id3 RUby library                                                                                      
require 'hexdump'

file_url = 'http://example.com/filename.mp3'

def get_remote_id3v2_tag( file_url )    # you would call this..
  id3v2tag_size = get_remote_id3v2_tag_size( file_url )
  if id3v2tag_size > 0
    buffer = get_remote_bytes(file_url, id3v2tag_size )
    tag2 = ID3::Tag2.new
    tag2.read_from_buffer( buffer )
    return tag2
  else
    return nil
  end
end

private
def get_remote_id3v2_tag_size( file_url )
  buffer = get_remote_bytes( file_url, 100 )
  if buffer.bytesize > 0
    return buffer.ID3v2tag_size
  else
    return 0
  end
end

private
def get_remote_bytes( file_url, n)
  uri = URI(file_url)
  size = n   # ID3v2 tags can be considerably larger, because of embedded album pictures                                 
  Net::HTTP.version_1_2  # make sure we use higher HTTP protocol version than 1.0                                        
  http = Net::HTTP.new(uri.host, uri.port)
  resp = http.get( file_url , {'Range' => "bytes=0-#{size-1}"} )                                                                     
  resp_code = resp.code.to_i
  if (resp_code >= 200 && resp_code < 300) then
    return resp.body
  else
    return ''
  end
end



get_remote_id3v2_tag_size( file_url )  
 => 2262

See:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35

http://en.wikipedia.org/wiki/Byte_serving

可以在此处找到如何下载零件文件的一些示例:

但请注意,似乎没有办法“在中间”开始下载

如何通过 HTTP 下载二进制文件?

http://unixgods.org/~tilo/Ruby/ID3/docs/index.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Ruby/Rails 中读取远程 MP3 文件的 ID3 标签? 的相关文章

  • 带有附加参数的redirect_to

    我是一个菜鸟 redirect to users url notice Succeed p p 然后我添加一个message它失败了 redirect to users url notice Succeed message test p p
  • Ruby 可选参数和多个参数

    我试图将方法的第一个参数设置为可选 后跟任意数量的参数 例如 def dothis value 0 args 我遇到的问题是 这似乎实际上不可能 当我打电话时dothis hey how are you good 我希望它将值设置为默认值
  • 将 ruby​​ 类转换为模块比使用改进更好的方法?

    Module refine http ruby doc org core 2 0 0 Module html method i refine方法接受一个类和一个块并返回一个细化模块 所以我想我可以定义 class Class def inc
  • 回形针不支持 .doc 文件

    在 Rails 4 0 2 中 我使用回形针 gem 上传文件 但它不支持 doc 文件 在文件上传字段下方 显示一条错误消息 扩展名与其内容不匹配 在模型中 检查内容类型的验证如下 validates attachment content
  • 下载所有 gems 依赖项

    我想通过下载任何所需的文件并将它们带到另一台计算机来安装指南针没有互联网连接 我已经下载了指南针的源包 当我在未连接的计算机上运行 gem 时 它抱怨缺少依赖项 有什么解决办法吗 这正是我遇到的问题 经过一段时间的搜索后 我找到了一个可以使
  • 两个 ruby​​ 进程之间的通信可能/容易吗?

    如果我有一个 ruby 脚本Daemon顾名思义 它作为守护进程运行 监视系统的某些部分并能够执行需要身份验证的命令 例如更改权限 是否有一种简单的方法来拥有第二个 ruby 脚本 例如client 与该脚本通信并向其发送命令 询问信息 我
  • Ruby gem 环境问题 - LoadError: no such file to load -- robots

    我正在尝试使用 anemone gem 编写一个爬虫 这需要 robots gem 不管出于什么原因 机器人绝对不会包括在内 这是我的一些环境信息 gem list d robots LOCAL GEMS robots 0 10 1 Aut
  • 用于验证目的的动态查找方法

    我正在使用 Ruby on Rails 3 0 7 我想在运行时查找一些记录以进行验证 但为该查找方法传递 设置一个值 也就是说 在我的班级中 我有以下内容 class Group lt lt ActiveRecord Base valid
  • 需要野科切吗?没有要加载的文件

    我正在尝试开始使用 Nokogiri 我运行了命令 gem install nokogiri 作为 Windows 7 64 位 中的管理员 控制台显示 已成功安装 和 已安装 1 个 gem 当我输入时 gem list local OR
  • 如何全局忽略 UTF-8 字符串中的无效字节序列?

    我有一个 Rails 应用程序从 Rails 版本 1 以来的迁移中幸存下来 我想忽略all其上的无效字节序列 以保持向后兼容性 我不知道输入编码 示例 gt Men xFC split n ArgumentError invalid by
  • 在 Rails 中呈现路由错误的 404 页面

    我试图在 Rails 中渲染集成的 404 页面作为例外 我尝试了这个 但仍然收到路由错误页面 posts controller rb def destroy if current user username post email post
  • Ruby on Rails Webpacker 找不到 asset_pack_path 下的图像

    我在使用 Ruby on Rails Webpacker 在视图中包含图像时遇到问题 当我尝试使用 html img 标签和 asset pack path 在我的视图中插入图像时 出现错误 我的图像位于app javascript ima
  • 如何加载 UrlHelper 和 Rails 中的路线?

    我想包括路线和link toPORO 中的方法 在控制台中测试这个时 我遇到了这个 如果我在没有路由助手的情况下包含 UrlHelper 一切似乎都工作正常 ruby 1 9 3 rc1 001 gt Rails version gt 3
  • 使用 Mechanize (Ruby) 进行基本身份验证和表单身份验证

    我正在尝试登录公司内部网上的一个站点 该站点具有基本身份验证弹出对话框和基于表单的身份验证 这是我正在使用的代码 导致 401 gt Net HTTPUnauthorized 错误 require rubygems require mech
  • 通过 SSL 发布 UTF-8 时,HEROKU 上出现“EOFError:已到达文件结尾”

    我在 heroku 上遇到了奇怪的错误 为了重现它 我必须使用请求正文中的任何 UTF 8 字符制作大的 超过几 KB HTTPS POST 这是一个例子 require net https require uri Accutally I
  • ruby中如何将binary32转换为float

    我有一个以 IEEE 32 编码的 binary32 如何将 0x0040EDC2 转换为 118 625 我尝试了几种打包和解包选项 但没有成功 IEEE http en wikipedia org wiki Single precisi
  • ubuntu 12.04 ruby​​ 2.0 Rails:找不到“thread_safe”

    我正在 ubuntu 12 04 上安装 Rails 使用以下方法手动安装 如何在 Ubuntu 12 04 上正确安装 ruby 2 0 0 https stackoverflow com questions 16222738 how t
  • 添加两个 ActiveRecord::Relation 对象[重复]

    这个问题在这里已经有答案了 如何将两个关系添加在一起 当我尝试 运算符时 它返回一个数组 但我需要它来返回关系 谢谢 麦克风 Try new relation relation merge another relation
  • 自动加载常量时检测到循环依赖

    我将 Rails 从版本 3 1 2 运行良好 升级到 4 0 并遇到以下错误 circular dependency detected while autoloading constant Foo 我创建了一个类ProductFactor
  • 如何在 Ruby 中重写 require ?

    我需要覆盖require来自 Ruby 文件 这是我的 start rb 应用程序入口点 所必需的 rubygems在此之前加载 位于 start rb 中 我尝试的所有操作都出现了堆栈溢出错误 正确的做法是什么 一般来说 如果你想修补一些

随机推荐

  • ImportError:dlopen:无法使用静态 TLS 加载更多对象

    我得到一个ImportError如果在之后导入 OpenCV cv2 tensorflow出口商 ubuntu ip 172 31 2 144 Downloads opencv 2 4 13 release python Python 2
  • 在 VBA 中声明 0 长度字符串数组 - 不可能吗?

    在VBA中真的不能声明0长度的数组吗 如果我尝试这个 Dim lStringArr 1 As String 我收到一个编译错误 指出范围没有值 如果我尝试欺骗编译器并在运行时重新调整 如下所示 ReDim lStringArr 1 我收到下
  • 清除 chrome webdriver 上的日期输入失败

    我在使用 selenium 从 firefoxdriver 切换到 chromedriver 时遇到了问题 它在 FF 中工作正常 但现在当我尝试清除日期输入字段时出现此错误 Caused by org openqa selenium In
  • 如何使用c#在datagridview中动态添加列

    如何使用c 在datagridview中动态添加列 例如 DataGridViewColumn col new DataGridViewTextBoxColumn col HeaderText Hi there int colIndex g
  • Angular 2 中指令评估的控制顺序

    我想在 Angular 2 中创建一个属性指令 它的主机上需要有一个单击处理程序 需要在评估元素上的其他指令之前添加单击处理程序 因为它控制对某些功能的访问 在 Angular 1 中 您可以在创建指令时使用优先级选项来执行此操作 Angu
  • ASP.NET MVC:@section 的目的是什么? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 对于 ASP NET MVC 应用程序 我看到这篇博客文章 作者 ScottGu 补充道
  • 安卓解密错误

    我正在尝试在 Android 应用程序中加密和解密字符串 但不断收到 InvalidKeyException 错误 这是我的代码 生成密钥方法 public void generateKeys Calendar cal Calendar g
  • Android,检测其他应用程序何时启动

    我正在尝试开发一个应用程序 阻止用户在没有密码的情况下访问指定的应用程序 场景是 用户点击 电子邮件 应用程序 例如 我的应用程序检测到应用程序的启动 我的应用程序确认它是 电子邮件 应用程序 我的应用程序在顶部打开一个视图 要求输入密码
  • 获取所有打开的 WPF 窗口

    我正在尝试获取所有打开的窗口 我尝试使用System Windows Application Current Windows但我在行中得到空指针异常foreach卢普群岛有人知道出了什么问题吗 public Window getWindow
  • C++14 标准中哪里说非 constexpr 函数不能在 constexpr 函数的定义中使用?

    例如 下面的代码不会编译 除非incr 被宣布constexpr int incr int n return n constexpr int foo int n 0 incr n return n 查看 C 14 中的 7 1 5 3 我们
  • 来自现有 SQLite 数据库的 Core Data 数据架构

    是否可以从现有的 SQLite 数据库文件生成 xcdatamodel CoreData 数据模型 我开发了一个 SQLite 数据库并针对它编写了一个 Java API 现在 我需要为同一个数据库 文件 编写等效的 iOS API 我不想
  • 安装 Eclipse IDE 时出错

    我正在尝试安装 eclipse IDE Java for Developers 但在安装过程中遇到以下错误 我的系统驱动器有足够的空间 过去我已经安装和卸载了 eclipse IDE 那么这会给我重新安装带来任何问题吗 10 50 59 E
  • 管道作业 - 向上游传递参数?

    TL DR 显然 在 Jenkins 管道作业中 您可以轻松地将参数传递给下游 我想知道的是你能否通过它们upstream 使用案例 我们有三份工作 job one job two and job three 这些通常单独运行 因为只需要一
  • iPhone - 以编程方式删除状态栏

    我制作了一个应用程序来实现 iPhone 的相机 当用户完成选择图像后 状态栏会重新出现 如何确保状态栏保持隐藏状态 这是我的代码 IBAction pickImage id sender UIImagePickerController p
  • Firebase 存储安全规则

    我刚刚开始使用 Firebase 并且能够读取 写入 编辑 删除数据库 在我的应用程序中 我仅向用户显示数据 如果他 她有权访问数据 我通过创建一个用户节点和另一个节点 称为服务 并引用该用户子节点中的服务来做到这一点 我以前从未使用过 F
  • 如何在express router中使用body-parser?

    我有一个具有对象的 post api 但我无法在控制台中打印它的抛出未定义我以为我缺少主体解析器 但在添加主体解析器后我看到错误body parser deprecated bodyParser use individual json ur
  • 当 SQL 数据库添加新行而不进行轮询时,C# Azure 函数触发

    有没有一种方法可以在每次将新数据库行添加到 SQL azure 数据库时调用 Azure 函数 理想情况下没有任何基于计时器的轮询 我知道这可以在 blob 存储上完成 但没有找到在 Azure 函数上执行此操作的方法 提前致谢 Funct
  • 未命名命名空间访问规则

    我正在查看部分7 3 1 1在 C 03 标准中 期望找到未命名命名空间中定义的项的访问规则的一些描述 对于未命名的命名空间 规则似乎有点不同 因为您无法完全限定对其中的项目的访问权限 我知道至少在同一个翻译单元中 人们可以访问未命名名称空
  • 无法在带有 glassfish 服务器的 ubuntu 上使用 intelliJ 在调试模式下运行 Web 应用程序

    在 ubuntu 12 04 上的 intelliJ 12 0 和 glassfish 3 1 2 2 中 我尝试在调试模式下启动我的 Web 应用程序 但收到以下错误消息 Error starting domain domain1 The
  • 在 Ruby/Rails 中读取远程 MP3 文件的 ID3 标签?

    使用 Ruby 如何解析远程 mp3 文件的 ID3 标签而不将整个文件下载到磁盘 这个问题已经被问到Java and 银光 但没有红宝石 Edit 查看 Java 答案 似乎可以 HTTP 支持 仅下载文件的尾部 即标签所在的位置 这可以