*исправления по считыванию данных без BOM
*добавлены работающие тесты
This commit is contained in:
1 parent
d03f6214aa
commit
aa04fd4df0
11 files changed
+191
-55
No files matched your search
+2
-2
@@ -10,7 +10,7 @@ pub enum EnumID3v24 as u8 {
|
||||
tcon
|
||||
tcop
|
||||
apic
|
||||
comment
|
||||
txxx
|
||||
unknown
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@ pub enum EnumID3v23 as u8 {
|
||||
tcon
|
||||
tcop
|
||||
apic
|
||||
comment
|
||||
txxx
|
||||
unknown
|
||||
}
|
||||
+12
-3
@@ -54,10 +54,19 @@ fn (mut frame Frame) fill(bytes []u8, start_position u64, idv3_version u8) {
|
||||
// Фрейм целиком вместе с заголовком, чтобы записать его обратно без изменений
|
||||
frame.apic = bytes[frame.start..frame.end]
|
||||
} else {
|
||||
// Выбор шага в записимости от версии ID3
|
||||
stride := if idv3_version == 3 { 13 } else { 11 }
|
||||
// Данные начинаются после 10 байт заголовка и байта кодировки
|
||||
mut data_start := frame.start + 11
|
||||
|
||||
// UTF-16 с BOM (01): 2 байта маркера, по ним определяется порядок байт
|
||||
if frame.encoding_name_idx == 1 && data_start + 2 <= frame.end {
|
||||
if bytes[data_start] == 0xFE && bytes[data_start + 1] == 0xFF {
|
||||
frame.encoding_name = "UTF-16BE"
|
||||
}
|
||||
data_start += 2
|
||||
}
|
||||
|
||||
// Замыкающие нули не относятся к данным
|
||||
frame.data = (iconv.encoding_to_vstring(bytes[frame.start+u64(stride)..frame.end], frame.encoding_name) or { "" }).trim_right('\x00')
|
||||
frame.data = (iconv.encoding_to_vstring(bytes[data_start..frame.end], frame.encoding_name) or { "" }).trim_right('\x00')
|
||||
|
||||
frame.addition = bytes[frame.start..frame.start + 10]
|
||||
}
|
||||
|
||||
+25
-20
@@ -48,7 +48,7 @@ pub fn (id3v1 ID3v1) to_v23() ID3v23 {
|
||||
tyer: metadata.Frame{
|
||||
data: id3v1.year
|
||||
}
|
||||
comment: metadata.Frame{
|
||||
txxx: metadata.Frame{
|
||||
data: id3v1.comment
|
||||
}
|
||||
}
|
||||
@@ -59,23 +59,24 @@ pub fn (id3v1 ID3v1) to_v23() ID3v23 {
|
||||
fn cut_or_trim(data string, capacity i8) []u8 {
|
||||
mut final_data := []u8{len: capacity, init: 0}
|
||||
|
||||
|
||||
bytes_data := iconv.vstring_to_encoding(data, "CP1251") or { []u8{len: capacity} }
|
||||
if data.len > 0 {
|
||||
bytes_data := iconv.vstring_to_encoding(data, "CP1251") or { []u8{len: capacity} }
|
||||
|
||||
diff := capacity - bytes_data.len
|
||||
if diff > 0 {
|
||||
for i, d in bytes_data {
|
||||
final_data[i] = d
|
||||
diff := capacity - bytes_data.len
|
||||
if diff > 0 {
|
||||
for i, d in bytes_data {
|
||||
final_data[i] = d
|
||||
}
|
||||
} else {
|
||||
final_data = bytes_data.clone()[..capacity]
|
||||
}
|
||||
} else {
|
||||
final_data = bytes_data.clone()[..capacity]
|
||||
}
|
||||
|
||||
return final_data
|
||||
}
|
||||
|
||||
// Перевести тэг в байты
|
||||
pub fn (id3v1 ID3v1) to_bytes() []u8 {
|
||||
pub fn (mut id3v1 ID3v1) to_bytes() []u8 {
|
||||
mut bytes := []u8{cap: 128}
|
||||
|
||||
bytes << "TAG".bytes()
|
||||
@@ -88,23 +89,27 @@ pub fn (id3v1 ID3v1) to_bytes() []u8 {
|
||||
// bytes << cut_or_trim(id3v1.track, i8(2))
|
||||
bytes << if id3v1.track.len != 0 { [u8(0), id3v1.track.u8()]} else { [u8(1), u8(0)] }
|
||||
|
||||
id_genre := Genre.from(id3v1.genre) or { Genre.unknown }
|
||||
id_genre := Genre.from(id3v1.genre.to_lower()) or { Genre.unknown }
|
||||
bytes << u8(id_genre) // cut_or_trim([u8(id_genre)], i8(2))
|
||||
|
||||
id3v1.embedded = true
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
// Добавление изменённого тэга
|
||||
pub fn (id3v1 ID3v1) insert(mut audio File, position i8) []u8 {
|
||||
bytes_tag := id3v1.to_bytes()
|
||||
// Уcтановка указателя на последний байт
|
||||
audio.seek(0, os.SeekMode.end) or { panic(err) }
|
||||
// Положение указателя
|
||||
size := audio.tell() or { panic(err) }
|
||||
// Чтение всех байта, кроме последних 128
|
||||
mut all_bytes := audio.read_bytes(int(size))#[..position]
|
||||
pub fn (mut id3v1 ID3v1) insert(mut audio File, position i8) []u8 {
|
||||
// if !id3v1.embedded {
|
||||
bytes_tag := id3v1.to_bytes()
|
||||
// Уcтановка указателя на последний байт
|
||||
audio.seek(0, os.SeekMode.end) or { panic(err) }
|
||||
// Положение указателя
|
||||
size := audio.tell() or { panic(err) }
|
||||
// Чтение всех байта, кроме последних 128
|
||||
mut all_bytes := audio.read_bytes(int(size))#[..position]
|
||||
|
||||
all_bytes << bytes_tag
|
||||
all_bytes << bytes_tag
|
||||
// }
|
||||
|
||||
return all_bytes
|
||||
}
|
||||
+5
-2
@@ -58,7 +58,10 @@ pub fn (mut tag ID3v23) add_frame(frame Frame) {
|
||||
}
|
||||
.apic {
|
||||
tag.apic = frame
|
||||
}
|
||||
}
|
||||
.txxx {
|
||||
tag.txxx = frame
|
||||
}
|
||||
else {
|
||||
tag.others << frame
|
||||
}
|
||||
@@ -96,7 +99,7 @@ pub fn (id3v23 ID3v23) to_v1() ID3v1 {
|
||||
album: id3v23.talb.data
|
||||
track: id3v23.trck.data.split("/")[0]
|
||||
year: id3v23.tyer.data
|
||||
comment: id3v23.comment.data
|
||||
comment: id3v23.txxx.data
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -35,6 +35,9 @@ pub fn (mut tag ID3v24) add_frame(frame Frame) {
|
||||
.apic {
|
||||
tag.apic = frame
|
||||
}
|
||||
.txxx {
|
||||
tag.txxx = frame
|
||||
}
|
||||
else {
|
||||
tag.others << frame
|
||||
}
|
||||
@@ -71,7 +74,7 @@ pub fn (id3v24 ID3v24) to_v1() ID3v1 {
|
||||
album: id3v24.talb.data
|
||||
track: id3v24.trck.data.split('/')[0]
|
||||
year: id3v24.tdrc.data
|
||||
comment: id3v24.comment.data
|
||||
comment: id3v24.txxx.data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -17,8 +17,11 @@ pub struct ID3v1 {
|
||||
@[heap; minify]
|
||||
pub struct ID3v23 {
|
||||
pub mut:
|
||||
size u64 // Размер тэга
|
||||
tit2 Frame // Название аудиодорожки
|
||||
// Размер тэга
|
||||
size u64
|
||||
// Название аудиодорожки
|
||||
tit2 Frame
|
||||
|
||||
tpe1 Frame // Автор
|
||||
tpe2 Frame // Исполнитель
|
||||
talb Frame // Название альбома
|
||||
@@ -27,9 +30,10 @@ pub struct ID3v23 {
|
||||
tcon Frame // Жанр
|
||||
tcop Frame // Композитор (автор)
|
||||
apic Frame // Обложка
|
||||
comment Frame // Комментарий
|
||||
txxx Frame // Комментарий
|
||||
unknown Frame // Затычка
|
||||
others []Frame // Остальные фреймы
|
||||
encoded_header []u8
|
||||
embedded bool // Присутвует ли тэг
|
||||
version u8 = 3 // Версия тэга
|
||||
title string = "ID3"
|
||||
@@ -59,7 +63,7 @@ pub struct ID3v24 {
|
||||
// Обложка
|
||||
apic Frame
|
||||
// Комментарий
|
||||
comment Frame
|
||||
txxx Frame
|
||||
// Затычка
|
||||
modified_frames []Frame
|
||||
// Остальные фреймы
|
||||
|
||||
@@ -105,8 +105,6 @@ pub fn encode_header[T](mut id3v T) {
|
||||
// Количество нулей в конце тэга
|
||||
const tag_padding = 256
|
||||
|
||||
type ID3vType = ID3v23 | ID3v24
|
||||
|
||||
// Формируем полный полный тэг в байтах
|
||||
pub fn encode_embed_tags[T](mut id3v2 T) {
|
||||
// Проход по всем полям стуктуры
|
||||
|
||||
Reference in new issue
Block a user