Project1
标题: 大家看看这个获取MP3文件基本信息的脚本 [打印本页]
作者: RyanBern 时间: 2014-11-21 16:31
标题: 大家看看这个获取MP3文件基本信息的脚本
本帖最后由 RyanBern 于 2014-11-21 21:10 编辑
应@精灵使者 的要求,写了一个能够获取MP3文件信息的脚本。因为脚本还不是很成熟,不能完全解决MP3文件的信息获取问题,所以放在了RM讨论区,等完善之后可以考虑放到技术发布区。不过需要这个脚本的人不多,放上去也不知有什么用。
问题的核心在于如何获取MP3文件内容,我查了一堆资料(这里不得不吐槽我们的百度,所有的资料都是copy-paste的,而且都有错误),最后只能照样子写了一个。经过多次测试,该脚本不能处理所有MP3的信息,而且有时候会报错。大家看看我是不是遗漏了些什么。
由于XP的版本限制,无法读取中文信息,这点大家也帮忙想想有没有解决方法。
我参考的官方MP3数据结构网址:
www.id3.org
module Audio
class Mp3Data
attr_accessor :title
attr_accessor :artist
attr_accessor :album
attr_accessor :year
attr_accessor :comments
attr_accessor :genre
attr_accessor :track
end
def initialize
@title = ""
[url=home.php?mod=space&uid=1953775]@artist[/url] = ""
@album = ""
@year = ""
@comments = ""
@genre = ""
@track = ""
end
def self.get_playing_bgm_info_mp3_id3v2
filename = "Audio/BGM/" + $game_system.playing_bgm.name + ".mp3"
file = File.open(filename, "r")
info = Mp3Data.new
buffer = file.read(10)
if buffer[0...3] == "ID3"
size = buffer[6...10]
total_size = (size[0]&0x7F) * 0x200000 + (size[1]&0x7F) * 0x4000 + (size[2]&0x7F) * 0x80 +(size[3]&0x7F)
while total_size > 0
buffer = file.read(10)
break if buffer.nil?
total_size -= 10
tag = buffer[0...4]
size = buffer[4...8]
current_size = size[0] * 0x1000000 + size[1]* 0x10000 + size[2] * 0x100 + size[3]
break if current_size == 0
buffer = file.read(current_size)
total_size -= current_size
case tag
when "TIT2"
info.title = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "TPE1"
info.artist = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "TYER"
info.year = buffer.gsub(/[^0-9]+/, "")
when "TRCK"
info.track = buffer.gsub(/[^0-9\/]/, "")
when "TALB"
info.album = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "TCON"
info.genre = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "COMM"
info.comments = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
end
end
end
file.close
return info
end
end
module Audio
class Mp3Data
attr_accessor :title
attr_accessor :artist
attr_accessor :album
attr_accessor :year
attr_accessor :comments
attr_accessor :genre
attr_accessor :track
end
def initialize
@title = ""
[url=home.php?mod=space&uid=1953775]@artist[/url] = ""
@album = ""
@year = ""
@comments = ""
@genre = ""
@track = ""
end
def self.get_playing_bgm_info_mp3_id3v2
filename = "Audio/BGM/" + $game_system.playing_bgm.name + ".mp3"
file = File.open(filename, "r")
info = Mp3Data.new
buffer = file.read(10)
if buffer[0...3] == "ID3"
size = buffer[6...10]
total_size = (size[0]&0x7F) * 0x200000 + (size[1]&0x7F) * 0x4000 + (size[2]&0x7F) * 0x80 +(size[3]&0x7F)
while total_size > 0
buffer = file.read(10)
break if buffer.nil?
total_size -= 10
tag = buffer[0...4]
size = buffer[4...8]
current_size = size[0] * 0x1000000 + size[1]* 0x10000 + size[2] * 0x100 + size[3]
break if current_size == 0
buffer = file.read(current_size)
total_size -= current_size
case tag
when "TIT2"
info.title = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "TPE1"
info.artist = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "TYER"
info.year = buffer.gsub(/[^0-9]+/, "")
when "TRCK"
info.track = buffer.gsub(/[^0-9\/]/, "")
when "TALB"
info.album = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "TCON"
info.genre = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
when "COMM"
info.comments = buffer.gsub(/[^0-9A-Za-z_ ]+/, "")
end
end
end
file.close
return info
end
end
作者: chd114 时间: 2014-11-21 18:24
你可以拿永夜的原声带试试看···
作者: taroxd 时间: 2014-11-21 18:53
吐槽一下,楼主查技术类资料竟然用百度……
作者: 精灵使者 时间: 2014-11-21 23:36
本帖最后由 精灵使者 于 2014-11-22 00:07 编辑
那个,不需要获取MP3的ID3标签啦。
只需要获取正在播放的文件名就可以了的说。
补充:
精灵想要的是这种效果:
获取BGM音乐名,然后当BGM/ME变化的时候,在右下角显示BGM的名称(可以使用 - 符号分割,类似于: 01 - Title Theme - Kan Gao.mp3)之类的
也就是说屏幕右下角会显示:
BGM:
01
Title Theme
Kan Gao
作者: 路路 时间: 2014-11-22 01:32
提示: 作者被禁止或删除 内容自动屏蔽
作者: RyanBern 时间: 2014-11-22 10:34
本帖最后由 精灵使者 于 2014-11-24 18:37 编辑
精灵使者 发表于 2014-11-21 23:36 
那个,不需要获取MP3的ID3标签啦。
只需要获取正在播放的文件名就可以了的说。
补充:
写了一个循环显示BGM的脚本,没有做ME的,可以试试效果。
class BGM_Display
def initialize
@bgm = nil
@me = nil
@waiting = 0
@sprite1 = Sprite.new
@sprite2 = Sprite.new
@sprite1.bitmap = Bitmap.new(160, 32)
@sprite2.bitmap = Bitmap.new(160, 224)
@sprite2.src_rect = Rect.new(0, 0, 160, 32)
self.x = 480
self.y = 416
self.z = 999
refresh
end
def refresh
if @me == nil || @me.name ==""
if @bgm == nil || @bgm.name == ""
@sprite2.bitmap.clear
return
end
@sprite1.bitmap.clear
@sprite1.bitmap.draw_text(0, 0, 160, 32, "BGM:")
@texts = @bgm.name.split(/-/)
else
@sprite1.bitmap.clear
@sprite1.bitmap.draw_text(0, 0, 160, 32, "ME:")
@texts = @me.name.split(/-/)
end
([email]0...@texts.size[/email]).each do |i|
draw_item(i)
end
end
def draw_item(i)
x = 4
y = 32 * (2 * i + 1)
@sprite2.bitmap.fill_rect(x, y, 160, 32, Color.new(0,0,0,0))
@sprite2.bitmap.draw_text(x, y ,160, 32, @texts[i])
end
def x=(x)
@sprite1.x = x
@sprite2.x = x
end
def y=(y)
@sprite1.y = y
@sprite2.y = y + 32
end
def z=(z)
@sprite1.z = z
@sprite2.z = z
end
def update
if $game_temp.playing_me != nil
@me = $game_temp.playing_me
$game_temp.playing_me = nil
refresh
@sprite2.src_rect.y = 0
return
end
if $game_system.playing_bgm != @bgm
@bgm = $game_system.playing_bgm
refresh
@sprite2.src_rect.y = 0
return
end
if @waiting > 0
@waiting -= 1
return
end
@sprite2.src_rect.y += 1
if @sprite2.src_rect.y >= 192
@sprite2.src_rect.y -= 192
if @me != nil
@me = nil
refresh
end
end
if @sprite2.src_rect.y % 64 == 32
@waiting = 40
end
end
def dispose
@sprite1.bitmap.dispose
@sprite2.bitmap.dispose
@sprite1.dispose
@sprite2.dispose
end
end
class Game_Temp
attr_accessor :playing_me
end
class Game_System
alias rb_me_play_20141124 me_play
def me_play(me)
$game_temp.playing_me = me
rb_me_play_20141124(me)
end
end
class Scene_Map
alias rb_main_20141122 main
def main
@bgm_display = BGM_Display.new
rb_main_20141122
@bgm_display.dispose
end
alias rb_update_20141122 update
def update
@bgm_display.update
rb_update_20141122
end
end
class BGM_Display
def initialize
@bgm = nil
@me = nil
@waiting = 0
@sprite1 = Sprite.new
@sprite2 = Sprite.new
@sprite1.bitmap = Bitmap.new(160, 32)
@sprite2.bitmap = Bitmap.new(160, 224)
@sprite2.src_rect = Rect.new(0, 0, 160, 32)
self.x = 480
self.y = 416
self.z = 999
refresh
end
def refresh
if @me == nil || @me.name ==""
if @bgm == nil || @bgm.name == ""
@sprite2.bitmap.clear
return
end
@sprite1.bitmap.clear
@sprite1.bitmap.draw_text(0, 0, 160, 32, "BGM:")
@texts = @bgm.name.split(/-/)
else
@sprite1.bitmap.clear
@sprite1.bitmap.draw_text(0, 0, 160, 32, "ME:")
@texts = @me.name.split(/-/)
end
([email]0...@texts.size[/email]).each do |i|
draw_item(i)
end
end
def draw_item(i)
x = 4
y = 32 * (2 * i + 1)
@sprite2.bitmap.fill_rect(x, y, 160, 32, Color.new(0,0,0,0))
@sprite2.bitmap.draw_text(x, y ,160, 32, @texts[i])
end
def x=(x)
@sprite1.x = x
@sprite2.x = x
end
def y=(y)
@sprite1.y = y
@sprite2.y = y + 32
end
def z=(z)
@sprite1.z = z
@sprite2.z = z
end
def update
if $game_temp.playing_me != nil
@me = $game_temp.playing_me
$game_temp.playing_me = nil
refresh
@sprite2.src_rect.y = 0
return
end
if $game_system.playing_bgm != @bgm
@bgm = $game_system.playing_bgm
refresh
@sprite2.src_rect.y = 0
return
end
if @waiting > 0
@waiting -= 1
return
end
@sprite2.src_rect.y += 1
if @sprite2.src_rect.y >= 192
@sprite2.src_rect.y -= 192
if @me != nil
@me = nil
refresh
end
end
if @sprite2.src_rect.y % 64 == 32
@waiting = 40
end
end
def dispose
@sprite1.bitmap.dispose
@sprite2.bitmap.dispose
@sprite1.dispose
@sprite2.dispose
end
end
class Game_Temp
attr_accessor :playing_me
end
class Game_System
alias rb_me_play_20141124 me_play
def me_play(me)
$game_temp.playing_me = me
rb_me_play_20141124(me)
end
end
class Scene_Map
alias rb_main_20141122 main
def main
@bgm_display = BGM_Display.new
rb_main_20141122
@bgm_display.dispose
end
alias rb_update_20141122 update
def update
@bgm_display.update
rb_update_20141122
end
end
作者: 龙和许也 时间: 2014-11-25 11:52
可恶~,居然在这讨论这些我看不懂的东西!!
脚本!!,看我不把你学会!!
作者: 寒冷魔王 时间: 2014-11-28 15:54
本帖最后由 寒冷魔王 于 2014-11-28 16:01 编辑
看楼主,猜语言,猜错了= =
还以为会用C#呢……
另外作为一名Java菜鸟想问一下Ruby怎样调用用Java写好的程序?
百度说是实例加载jar的,不过那个需不需要Java环境?
如果加载需要运行Java的话,我还是再学一学C#吧= =
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |