*всё работает
This commit is contained in:
1 parent
aa04fd4df0
commit
ffa8d80875
6 files changed
+124
-154
No files matched your search
@@ -1,128 +0,0 @@
|
|||||||
module main
|
|
||||||
|
|
||||||
import os
|
|
||||||
// import io
|
|
||||||
import metadata
|
|
||||||
|
|
||||||
fn id3(){
|
|
||||||
// mut audio := os.open("./data/АЛИСА 11000.mp3") or { panic(err) }
|
|
||||||
// mut audio := os.open("./data/Глава 2. 16 и 17 июля.mp3") or { panic(err) }
|
|
||||||
// mut audio := os.open("./out.mp3") or { panic(err) }
|
|
||||||
mut audio := os.open("./data/test_id3v23.mp3") or { panic(err) }
|
|
||||||
// mut audio := os.open("./data/01_01.mp3") or { panic(err) }
|
|
||||||
// mut audio := os.open("./test.mp3") or { panic(err) }
|
|
||||||
|
|
||||||
defer {
|
|
||||||
audio.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
mut wav := metadata.Audio{}
|
|
||||||
wav.detect_tags(mut audio)
|
|
||||||
|
|
||||||
println(wav.id3v1.embedded)
|
|
||||||
println(wav.id3v23.embedded)
|
|
||||||
println(wav.id3v24.embedded)
|
|
||||||
|
|
||||||
if wav.id3v1.embedded {
|
|
||||||
last_bytes := metadata.get_bytes(mut audio, -128, 128)
|
|
||||||
wav.id3v1.get_metadata(last_bytes)
|
|
||||||
|
|
||||||
// wav.id3v1.genre = "Rock"
|
|
||||||
// wav.id3v1.title = "Test title"
|
|
||||||
// wav.id3v1.artist = "Test artist"
|
|
||||||
// wav.id3v1.album = "Test albulm"
|
|
||||||
// wav.id3v1.comment = "2/5"
|
|
||||||
// wav.id3v1.track = "2/5"
|
|
||||||
|
|
||||||
println(wav.id3v1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if wav.id3v23.embedded {
|
|
||||||
wav.id3v23.get_full_size(mut audio)
|
|
||||||
wav.id3v23.fill_tags(mut audio)
|
|
||||||
println(wav.id3v23.to_v1())
|
|
||||||
wav.id3v23.tit2.encode_size(3)
|
|
||||||
tit2 := wav.id3v23.tit2.get_encoded_frame_tag(3)
|
|
||||||
println(tit2)
|
|
||||||
println(wav.id3v23)
|
|
||||||
}
|
|
||||||
|
|
||||||
if wav.id3v24.embedded {
|
|
||||||
wav.id3v24.get_full_size(mut audio)
|
|
||||||
wav.id3v24.fill_tags(mut audio)
|
|
||||||
println(wav.id3v24.to_v1())
|
|
||||||
// wav.id3v24.tit2.encode_size(4)
|
|
||||||
|
|
||||||
// flex := wav.id3v24.talb.get_encoded_frame_tag(4)
|
|
||||||
|
|
||||||
// println(flex)
|
|
||||||
|
|
||||||
// println(wav.id3v24.tdrc.data)
|
|
||||||
// wav.id3v24.tdrc.set_data("2017")
|
|
||||||
|
|
||||||
// // enc_size := metadata.encode_header_size(wav.id3v24.size, wav.id3v24.version)
|
|
||||||
// // println(enc_size)
|
|
||||||
// wav.id3v24.tit2.set_data("2017")
|
|
||||||
// wav.id3v24.tpe1.init("tpe1")
|
|
||||||
// wav.id3v24.tpe1.set_data("Hello")
|
|
||||||
// wav.id3v24.tpe2.init("tpe2")
|
|
||||||
// wav.id3v24.tpe2.set_data("Hello2")
|
|
||||||
// // metadata.encode_header(mut wav.id3v24)
|
|
||||||
// // println(wav.id3v24.encoded_header)
|
|
||||||
// // println(wav.id3v24.tpe1.name)
|
|
||||||
|
|
||||||
// wav.id3v24.encode_embed_tags()
|
|
||||||
// println(wav.id3v24.encoded_header.len)
|
|
||||||
|
|
||||||
// wav.id3v24.insert_tags_into_audio(mut audio)
|
|
||||||
|
|
||||||
// // println(wav.id3v24)
|
|
||||||
|
|
||||||
// mut f := os.create("./temp.mp3") or { panic(err) }
|
|
||||||
|
|
||||||
// f.write(wav.id3v24.encoded_header) or { panic(err) }
|
|
||||||
// f.close()
|
|
||||||
|
|
||||||
// println(wav.id3v24)
|
|
||||||
// mut audio_2 := os.open("./out.mp3") or { panic(err) }
|
|
||||||
|
|
||||||
// data := io.read_all(reader: audio_2) or { [u8(0), u8(0), u8(0), u8(0)] }
|
|
||||||
// println(data)
|
|
||||||
println(wav.id3v24.size)
|
|
||||||
println(wav.id3v24.encoded_header)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// println(wav.id3v23)
|
|
||||||
// println(wav.id3v23.tit2)
|
|
||||||
|
|
||||||
|
|
||||||
// converted_idv31 := wav.id3v1.to_v23()
|
|
||||||
// println(converted_idv31)
|
|
||||||
// println(last_bytes)
|
|
||||||
|
|
||||||
// flex := wav.id3v1.to_bytes()
|
|
||||||
|
|
||||||
// audio.seek(-1, os.SeekMode.end) or { panic(err) }
|
|
||||||
|
|
||||||
// flex1 := audio.tell() or { panic(err) }
|
|
||||||
|
|
||||||
// mut all_bytes := audio.read_bytes(int(flex1))#[..-128]
|
|
||||||
|
|
||||||
// all_bytes << flex
|
|
||||||
|
|
||||||
// println(all_bytes.len)
|
|
||||||
// println(int(flex1))
|
|
||||||
|
|
||||||
// all_bytes := wav.id3v1.insert(mut audio, -128)
|
|
||||||
|
|
||||||
// os.write_bytes("./test.mp3", new_bytes) or { panic(err) }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main(){
|
|
||||||
id3()
|
|
||||||
}
|
|
||||||
@@ -123,7 +123,6 @@ pub fn (mut frame Frame) get_encoded_frame_tag(idv3_version u8) []u8 {
|
|||||||
// Название тэга
|
// Название тэга
|
||||||
mut encoded_tag := frame.name.bytes()
|
mut encoded_tag := frame.name.bytes()
|
||||||
|
|
||||||
|
|
||||||
// Четыре числа на закодированный размер
|
// Четыре числа на закодированный размер
|
||||||
encoded_tag << frame.encoded_size
|
encoded_tag << frame.encoded_size
|
||||||
// Флаги, оставляем пустыми
|
// Флаги, оставляем пустыми
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module metadata
|
module metadata
|
||||||
|
|
||||||
import os { File }
|
import os { File }
|
||||||
|
import io { read_all }
|
||||||
|
|
||||||
// 00: ISO-8859-1 (1 байт на символ).
|
// 00: ISO-8859-1 (1 байт на символ).
|
||||||
// 01: UTF-16 с BOM (2 байта на символ + 2 байта маркер).
|
// 01: UTF-16 с BOM (2 байта на символ + 2 байта маркер).
|
||||||
@@ -103,3 +104,13 @@ pub fn (id3v23 ID3v23) to_v1() ID3v1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut id3v23 ID3v23) insert_tags_into_audio(mut audio File) {
|
||||||
|
full_part := read_all(reader: audio) or { panic(err) }
|
||||||
|
|
||||||
|
// Размер старого тэга берётся из файла, id3v23.size уже хранит размер нового.
|
||||||
|
// В заголовке тэга размер syncsafe даже в v2.3, поэтому get_size_v24
|
||||||
|
old_size := get_size_v24(full_part[6..10])
|
||||||
|
sound_part := full_part[int(old_size) + 10 .. ]
|
||||||
|
|
||||||
|
id3v23.encoded_header << sound_part
|
||||||
|
}
|
||||||
+42
-22
@@ -4,14 +4,22 @@ module metadata
|
|||||||
@[heap; minify]
|
@[heap; minify]
|
||||||
pub struct ID3v1 {
|
pub struct ID3v1 {
|
||||||
pub mut:
|
pub mut:
|
||||||
genre string// Жанр
|
// Жанр
|
||||||
title string // Название аудиодорожки
|
genre string
|
||||||
artist string // Актёр озучания
|
// Название аудиодорожки
|
||||||
album string // Название альбома
|
title string
|
||||||
track string // Записывается как 2/5, что значит 2 трэк из 5
|
// Актёр озучания
|
||||||
year string // Год записи, может int нужно
|
artist string
|
||||||
comment string // Комментарий
|
// Название альбома
|
||||||
embedded bool // Присутвует ли тэг
|
album string
|
||||||
|
// Записывается как 2/5, что значит 2 трэк из 5
|
||||||
|
track string
|
||||||
|
// Год записи, может int нужно
|
||||||
|
year string
|
||||||
|
// Комментарий
|
||||||
|
comment string
|
||||||
|
// Присутвует ли тэг
|
||||||
|
embedded bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@[heap; minify]
|
@[heap; minify]
|
||||||
@@ -21,21 +29,33 @@ pub struct ID3v23 {
|
|||||||
size u64
|
size u64
|
||||||
// Название аудиодорожки
|
// Название аудиодорожки
|
||||||
tit2 Frame
|
tit2 Frame
|
||||||
|
// Автор
|
||||||
tpe1 Frame // Автор
|
tpe1 Frame
|
||||||
tpe2 Frame // Исполнитель
|
// Исполнитель
|
||||||
talb Frame // Название альбома
|
tpe2 Frame
|
||||||
tyer Frame // Год выпуска
|
// Название альбома
|
||||||
trck Frame // Номер трека
|
talb Frame
|
||||||
tcon Frame // Жанр
|
// Год выпуска
|
||||||
tcop Frame // Композитор (автор)
|
tyer Frame
|
||||||
apic Frame // Обложка
|
// Номер трека
|
||||||
txxx Frame // Комментарий
|
trck Frame
|
||||||
unknown Frame // Затычка
|
// Жанр
|
||||||
others []Frame // Остальные фреймы
|
tcon Frame
|
||||||
|
// Композитор (автор)
|
||||||
|
tcop Frame
|
||||||
|
// Обложка
|
||||||
|
apic Frame
|
||||||
|
// Комментарий
|
||||||
|
txxx Frame
|
||||||
|
// Затычка
|
||||||
|
unknown Frame
|
||||||
|
// Остальные фреймы
|
||||||
|
others []Frame
|
||||||
encoded_header []u8
|
encoded_header []u8
|
||||||
embedded bool // Присутвует ли тэг
|
// Присутвует ли тэг
|
||||||
version u8 = 3 // Версия тэга
|
embedded bool
|
||||||
|
// Версия тэга
|
||||||
|
version u8 = 3
|
||||||
title string = "ID3"
|
title string = "ID3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -99,7 +99,8 @@ pub fn encode_header[T](mut id3v T) {
|
|||||||
// Минорная версия и спец. флаги
|
// Минорная версия и спец. флаги
|
||||||
id3v.encoded_header << []u8{len: 2}
|
id3v.encoded_header << []u8{len: 2}
|
||||||
|
|
||||||
id3v.encoded_header << metadata.encode_header_size(id3v.size, id3v.version)
|
// Размер всего тэга в заголовке всегда syncsafe (по 7 бит в байте), в том числе в v2.3
|
||||||
|
id3v.encoded_header << metadata.encode_header_size(id3v.size, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Количество нулей в конце тэга
|
// Количество нулей в конце тэга
|
||||||
@@ -110,7 +111,8 @@ pub fn encode_embed_tags[T](mut id3v2 T) {
|
|||||||
// Проход по всем полям стуктуры
|
// Проход по всем полям стуктуры
|
||||||
mut tag_bytes := []u8{}
|
mut tag_bytes := []u8{}
|
||||||
|
|
||||||
$for field in id3v2.fields {
|
// Именно T.fields: с id3v2.fields V пропускает поля, которых нет в другом типе (tyer в ID3v24)
|
||||||
|
$for field in T.fields {
|
||||||
$if field.typ is Frame {
|
$if field.typ is Frame {
|
||||||
// Читаются только заполненные тэги
|
// Читаются только заполненные тэги
|
||||||
if id3v2.$(field.name).cur_size > 0 {
|
if id3v2.$(field.name).cur_size > 0 {
|
||||||
@@ -133,4 +135,4 @@ pub fn encode_embed_tags[T](mut id3v2 T) {
|
|||||||
id3v2.encoded_header = []u8{}
|
id3v2.encoded_header = []u8{}
|
||||||
encode_header(mut id3v2)
|
encode_header(mut id3v2)
|
||||||
id3v2.encoded_header << tag_bytes
|
id3v2.encoded_header << tag_bytes
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,72 @@ fn test_idv3v23() {
|
|||||||
assert id3v1.comment == "comment"
|
assert id3v1.comment == "comment"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_writeidv3v23() {
|
||||||
|
mut audio := os.open("./data/test_id3v23.mp3") or { panic(err) }
|
||||||
|
defer {
|
||||||
|
audio.close()
|
||||||
|
}
|
||||||
|
mut wav := metadata.Audio{}
|
||||||
|
wav.detect_tags(mut audio)
|
||||||
|
|
||||||
|
assert wav.id3v1.embedded == false, 'Тег показан false, а должен быть true'
|
||||||
|
assert wav.id3v23.embedded == true, 'Тег показан true, а должен быть false'
|
||||||
|
assert wav.id3v24.embedded == false, 'Тег показан true, а должен быть false'
|
||||||
|
wav.id3v23.get_full_size(mut audio)
|
||||||
|
wav.id3v23.fill_tags(mut audio)
|
||||||
|
|
||||||
|
// Изменение значений тэга
|
||||||
|
wav.id3v23.tit2.set_data("Test Title2")
|
||||||
|
wav.id3v23.tpe1.set_data("Test Author2")
|
||||||
|
wav.id3v23.tpe2.set_data("Test Narator2")
|
||||||
|
wav.id3v23.talb.set_data("Test Album2")
|
||||||
|
wav.id3v23.tyer.set_data("2027")
|
||||||
|
wav.id3v23.trck.set_data("7/7")
|
||||||
|
wav.id3v23.tcon.set_data("Rock2")
|
||||||
|
wav.id3v23.tcop.set_data("Test2")
|
||||||
|
wav.id3v23.txxx.set_data("comment2")
|
||||||
|
|
||||||
|
wav.id3v23.encode_embed_tags()
|
||||||
|
wav.id3v23.insert_tags_into_audio(mut audio)
|
||||||
|
|
||||||
|
os.write_bytes("./data/temp_v23.mp3", wav.id3v23.encoded_header) or { panic(err) }
|
||||||
|
|
||||||
|
// Чтение файла и проверка записи
|
||||||
|
mut temp_audio := os.open("./data/temp_v23.mp3") or { panic(err) }
|
||||||
|
defer {
|
||||||
|
temp_audio.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
mut temp_wav := metadata.Audio{}
|
||||||
|
temp_wav.detect_tags(mut temp_audio)
|
||||||
|
|
||||||
|
assert temp_wav.id3v1.embedded == false, 'Тег показан false, а должен быть true'
|
||||||
|
assert temp_wav.id3v23.embedded == true, 'Тег показан true, а должен быть false'
|
||||||
|
assert temp_wav.id3v24.embedded == false, 'Тег показан true, а должен быть false'
|
||||||
|
temp_wav.id3v23.get_full_size(mut temp_audio)
|
||||||
|
temp_wav.id3v23.fill_tags(mut temp_audio)
|
||||||
|
|
||||||
|
assert temp_wav.id3v23.tit2.data == "Test Title2"
|
||||||
|
assert temp_wav.id3v23.tpe1.data == "Test Author2"
|
||||||
|
assert temp_wav.id3v23.tpe2.data == "Test Narator2"
|
||||||
|
assert temp_wav.id3v23.talb.data == "Test Album2"
|
||||||
|
assert temp_wav.id3v23.tyer.data == "2027"
|
||||||
|
assert temp_wav.id3v23.trck.data == "7/7"
|
||||||
|
assert temp_wav.id3v23.tcon.data == "Rock2"
|
||||||
|
assert temp_wav.id3v23.tcop.data == "Test2"
|
||||||
|
assert temp_wav.id3v23.txxx.data == "comment2"
|
||||||
|
|
||||||
|
id3v1 := wav.id3v23.to_v1()
|
||||||
|
|
||||||
|
assert id3v1.genre == "Rock2"
|
||||||
|
assert id3v1.title == "Test Title2"
|
||||||
|
assert id3v1.artist == "Test Narator2"
|
||||||
|
assert id3v1.album == "Test Album2"
|
||||||
|
assert id3v1.track == "7"
|
||||||
|
assert id3v1.year == "2027"
|
||||||
|
assert id3v1.comment == "comment2"
|
||||||
|
}
|
||||||
|
|
||||||
// Проверка чтения id3v24
|
// Проверка чтения id3v24
|
||||||
fn test_idv3v24() {
|
fn test_idv3v24() {
|
||||||
mut audio := os.open("./data/test_id3v24.mp3") or { panic(err) }
|
mut audio := os.open("./data/test_id3v24.mp3") or { panic(err) }
|
||||||
|
|||||||
Reference in new issue
Block a user