9
septembre
2012
lecture et écriture de tags ID3 en Vala
septembre
2012
Un article de Rachel
Pas de commentaires
voici une nouvelle version de ma librairie. malheureusement, l’écriture ne comprend pas encore les images . dans une possible future version, j’arrive à gérer les différentes versions de tags ID3.
using System;
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
} using System;
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
} using System;
namespace TagLib
{
public interface SaveHandler
{
public abstract void Save();
}
public abstract class Frame
{
public Frame(Bytes bytes){}
public abstract Bytes Data {get;}
public abstract Bytes NextData {get;}
public abstract string Type {get;}
public abstract int Size {get;}
}
public abstract class Picture
{
public Picture(Bytes bytes){}
public abstract Bytes Buffer{get;}
public abstract string MimeType {get;}
public abstract Bytes Description {get;}
}
public class File
{
uint8[] data;
Bytes bytes;
string identifier;
TagLib.Tag tag;
Bytes raw_data;
int size;
File (string filename)
{
FileUtils.get_data(filename, out data);
bytes = new Bytes(data);
Encoding enc = new Encoding();
identifier = enc.GetString(bytes.slice(0,3));
}
public static File Create (string filename)
{
File file = new File(filename);
switch(file.identifier)
{
case "Ogg":
TagLibOgg.File f = new TagLibOgg.File(filename);
file.tag = f.Tag;
break;
case "ID3":
TagLibId3v2.File f = new TagLibId3v2.File(filename);
file.tag = f.Tag;
file.raw_data = f.RawData;
break;
}
return file;
}
public void Save ()
{
Encoding enc = new Encoding();
ByteArray array = new ByteArray();
ByteArray array2 = new ByteArray();
ByteArray array3 = new ByteArray();
if(tag.Title != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Title.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
size = array2.data.length;
stdout.printf (size.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(size-2));
array2.prepend (enc.GetBytes("TIT2").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Album != null){
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Album.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TALB").get_data ());
}
array3.append (array2.data);
array2 = new ByteArray();
if(tag.Artist != null){
stdout.printf (tag.Artist+"\n");
for(int i=0;i<tag.Title.length;i++){
array2.append(new uint8[]{(uint8)tag.Artist.get_char(i),0});
}
array2.prepend (new uint8[]{0,0,1,255,254});
int s = array2.data.length;
stdout.printf (s.to_string()+"\n");
array2.prepend (Convert.ToBytes.from_integer(s-2));
array2.prepend (enc.GetBytes("TPE1").get_data ());
}
array3.append (array2.data);
array.append (enc.GetBytes("ID3").get_data ());
array.append (new uint8[]{3,0,0});
array.append (Convert.ToBytes.from_integer(array3.data.length));
array.append (array3.data);
array.append (raw_data.get_data());
FileUtils.set_data ("test_de_merde.mp3",array.data);
}
public virtual Bytes RawData {get{return raw_data;}}
public virtual TagLib.Tag Tag {get{return tag;}}
}
public class Tag
{
string title;
string encoder;
string genre;
string artist;
string album;
TagLib.Picture picture;
public Tag(List frames){}
public virtual string Album {get{return album;} set{album = value;}}
public virtual string Artist {get{return artist;} set{artist = value;}}
public virtual string Genre {get{return genre;} set{genre = value;}}
public virtual string Encoder {get{return encoder;} set{encoder = value;}}
public virtual string Title {get{return title;} set{title = value;}}
public virtual TagLib.Picture Picture {get{return picture;} set{picture = value;}}
}
}
namespace TagLibOgg
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
public File(string filename)
{
base(filename);
uint8[] data;
FileUtils.get_data (filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
string s = "(Schaufenugget)";
int index = Encoding.IndexOf(bytes,s)+s.length;
int not = (int)bytes[index];
frame = new Frame(bytes.slice(index+4,bytes.length-1));
frames = new List();
for(int i=0; i<not; i++){
frames.append(frame);
frame = new Frame(frame.NextData);
if(frame.Type == "COVERART")break;
}
tag = new TagLibOgg.Tag(frames);
}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public Tag(List frames){
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames){
switch(frame.Type)
{
case "TITLE":
title = enc.GetString(frame.Data);
break;
case "ARTIST":
artist = enc.GetString(frame.Data);
break;
case "ENCODER":
encoder = enc.GetString(frame.Data);
break;
case "GENRE":
genre = enc.GetString(frame.Data);
break;
case "ALBUM":
album = enc.GetString(frame.Data);
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
int size;
string type;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
size = (int)bytes[0]+256*(int)bytes[1]+256*256*(int)bytes[2]+256*256*256*(int)bytes[3];
data = bytes.slice(4,4+size);
int i = Encoding.IndexOf(data,"=");
type = enc.GetString(data.slice(0,i));
data = data.slice(i+1,data.length);
next_data = bytes.slice(4+size,bytes.length-1);
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
}
namespace TagLibId3v2
{
public class File : TagLib.File
{
TagLib.Tag tag;
Bytes bytes;
List frames;
Encoding enc;
Frame frame;
int size;
uint8[] data;
Bytes raw_data;
public File(string filename)
{
base(filename);
FileUtils.get_data(filename,out data);
bytes = new Bytes(data);
enc = new Encoding();
frame = new Frame(bytes.slice(10,bytes.length-1));
frames = new List();
while(frame.Type!="APIC")
{
stdout.printf (frame.Type+"\n");
if(frame.NextData.get_data ()[0]>200 || frame.NextData.get_data ()[0]==0)break;
frames.append(frame);
frame = new Frame(frame.NextData);
}
frames.append(frame);
raw_data = frame.NextData;
int version;
if(data[3]==4)version = 1;
else version = 3;
tag = new TagLibId3v2.Tag(frames,version);
}
public override Bytes RawData {get{return raw_data;}}
public override TagLib.Tag Tag {get{return tag;}}
}
public class Tag : TagLib.Tag
{
string album;
string artist;
string genre;
string encoder;
string title;
TagLib.Picture picture;
public override string Album {get{return album;} set{album = value;}}
public override string Artist {get{return artist;} set{artist = value;}}
public override string Genre {get{return genre;} set{genre = value;}}
public override string Encoder {get{return encoder;} set{encoder = value;}}
public override string Title {get{return title;} set{title = value;}}
public override TagLib.Picture Picture {get{return picture;} set{picture = value;}}
public Tag(List frames, int version)
{
base(frames);
Encoding enc = new Encoding();
foreach(TagLib.Frame frame in frames)
{
switch(frame.Type){
case "TIT2":
title = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TENC":
encoder = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TCON":
genre = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TPE1":
artist = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "TALB":
album = enc.GetString(frame.Data.slice(version,frame.Data.length));
break;
case "APIC":
picture = new TagLibId3v2.Picture(frame.Data);
break;
default:
break;
}
}
}
}
public class Frame : TagLib.Frame
{
Encoding enc;
string type;
int size;
Bytes data;
Bytes next_data;
public Frame(Bytes bytes)
{
base(bytes);
enc = new Encoding();
type = enc.GetString(bytes.slice(0,4));
size = (int)bytes[7]+256*(int)bytes[6]+256*256*(int)bytes[5]+256*256*256*(int)bytes[4];
data = bytes.slice(10,10+size);
next_data = bytes.slice(10+size,bytes.length-1);
stdout.printf (next_data[0].to_string()+" "+next_data[1].to_string()+" "+next_data[2].to_string()+" "+next_data[3].to_string()+"\n");
}
public override Bytes Data {get{return data;}}
public override Bytes NextData {get{return next_data;}}
public override string Type {get{return type;}}
public override int Size {get{return size;}}
}
public class Picture : TagLib.Picture
{
int index;
Bytes description;
Bytes buffer;
string mime_type;
public Picture(Bytes bytes)
{
base(bytes);
for(int i=0; i4)return -1;
int a = 256*256*256*(int)bytes[0];
int b = 256*256*(int)bytes[1];
int c = 256*(int)bytes[2];
int d = (int)bytes[3];
int result = a+b+c+d;
return result;
}
public static int from_list_bytes(GLib.List list)
{
if(list.length()>4)return -1;
int a = 256*256*256*(int)list.nth_data(0);
int b = 256*256*(int)list.nth_data(1);
int c = 256*(int)list.nth_data(2);
int d = (int)list.nth_data(3);
int result = a+b+c+d;
return result;
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}
public class ToBytes
{
public static uint8[] from_integer(int number)
{
int a = number / (256*256*256);
number -= a*256*256*256;
int b = number / (256*256);
number -= b*256*256;
int c = number / 256;
number -= c*256;
uint8[] u = new uint8[4];
u[0] = (uint8)a;
u[1] = (uint8)b;
u[2] = (uint8)c;
u[3] = (uint8)number;
return u;
}
}
}
public class Encoding
{
public Encoding(){}
public string GetString(Bytes bytes)
{
string s = "";
foreach(uint8 u in bytes.get_data())
if(u!=0)s += ((char)u).to_string();
return s;
}
public Bytes GetBytes(string str)
{
uint8[] u = new uint8[str.length];
for(int i=0; i<str.length; i++)
u[i] = (uint8)str.get_char(i);
Bytes bytes = new Bytes(u);
return bytes;
}
public static int IndexOf(Bytes bytes, string str)
{
Encoding enc = new Encoding();
Bytes b = enc.GetBytes(str);
for(int i = 0; i < bytes.length-1-b.length; i++){
if(enc.GetString(bytes.slice(i,i+b.length))==str){
return i;
}
}
return -1;
}
}
}