Sep 27 2009

ปัญหาภาษาไทยกับ iTunes และ Windows

Category: .NETm3rLinEz @ 12:58

เป็นปัญหาเดียวกับเรื่องภาษาไทยเป็นตัวยึกยือ มันเกิดจากข้อมูลใน ID3 Tag (เป็นส่วนของไฟล์ที่ไว้บอกข้อมูลเกี่ยวกับเพลง) มันเก็บภาษาไทยโดยใช้ Encoding แบบนึง (มักจะเป็น Windows-874 / TIS620 ซัมติง …)

MP3TagProblem

อ่านหาวิธีแก้ตามเว็บบอร์ดชุมชนคนไทยก็พบวิธีแก้ง่ายๆอย่างนึงคือต้องไปเปลี่ยน Regional Settings ให้เป็นไทยหลายๆอัน แล้วจะดิสเพลย์ได้ถูกต้อง o__O! แล้วค่อยใช้ iTunes convert ID3 ให้กลายเป็นเวอร์ชันใหม่ๆ (ที่จะเป็น unicode รองรับหลายภาษา)

การทำแบบนี้มันก็มีปัญหาอยู่บ้าง เพราะพอเปลี่ยน Regional แล้วก็จะทำให้ไม่รู้ว่าอัลบั้มไหน convert ID3 ไปเรียบร้อยแล้วรึยัง (เพราะมันแสดงได้ถูกต้องทั้งหมด) อย่างตอนนี้ผมลง OS ใหม่เป็น Windows 7 อัลบั้มเก่าๆเน่าไปหลายอันอยู่ … ก็เลยเขียนโปรแกรม convert ดีกว่า! (นั่น …. หาเรื่องเขียนบลอกอะดิ๊ๆๆๆๆ)

ประเด็นสำคัญ

  • Tool สำหรับแปลง ID3 ที่เป็น encoding หนึ่งไปอีกอันนึงก็มีอยู่แล้วบ้าง แต่ส่วนใหญ่มักจะเป็นบน Linux กับ Mac หาของ Windows ไม่เจอ (หรือผมอาจจะตาถั่วเอง)
  • ใช้ Lib สำหรับอ่าน ID3 คือ TabLig Sharp
  • ใช้ Reflection ในการวนรอบ property ทุกอันที่เป็น string และ string[] เป็นครั้งแรกที่เริ่มเห็นคุณค่าของ relfection!
  • พอมันมี Library ภายนอกก็เลยมี DLL หลายอัน รวมให้เป็น EXE อันเดียวโดยใช้ ILMerge จะทำให้ ship ง่ายกว่า (แต่ยังไม่คิดจะ ship รอให้มี demand ก่อน ฮ่าๆ)
  • อันตรายมาก: ยังไม่มีวิธีเช็คเลยว่าไฟล์ไหนถูกแปลงไปแล้วบ้าง เพราะถ้าแปลงซ้ำกันสองครั้งมันจะทำให้เนื้อหาไฟล์พังไปเลย >_< โดนไปหนึ่งดอกเรียบร้อย
  • ตอนนี้ใช้ iTunes โดยให้มัน Consolidate Library แล้ว รู้สึกทำให้ย้ายของง่ายกว่า
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace ID3ConvertToUnicode
{
class Program
{
public static string FixThaiCodePage(string str)
{
if (str == null) return null;
byte[] raw = Encoding.Default.GetBytes(str);
string res = Encoding.GetEncoding("windows-874").GetString(raw);
return res;
}

public static string[] FixThaiCodePage(string[] strings)
{
string[] res = new string[strings.Length];
for (int i = 0; i < strings.Length; i++)
{
res[i] = FixThaiCodePage(strings[i]);
}
return res;
}

static void Main(string[] args)
{
string[] files = Directory.GetFiles(".");
foreach (string file in files)
{
if (!file.EndsWith(".mp3"))
continue;

Console.WriteLine("Converting: " + file);
TagLib.File music = TagLib.File.Create(file);

foreach (PropertyInfo pinfo in music.Tag.GetType().GetProperties())
{
if (!pinfo.CanRead || !pinfo.CanWrite)
continue;

if (pinfo.PropertyType == typeof(string))
{
string s = pinfo.GetValue(music.Tag, null) as string;
s = FixThaiCodePage(s);
pinfo.SetValue(music.Tag, s, null);
}

if (pinfo.PropertyType == typeof(string[]))
{
string[] s = pinfo.GetValue(music.Tag, null) as string[];
s = FixThaiCodePage(s);
pinfo.SetValue(music.Tag, s, null);
}
}
music.Save();
Console.WriteLine();
}

}
}
}

ilmerge /target:winexe  /out:ID3Retag.exe 
ID3ConvertToUnicode.exe policy.2.0.taglib-sharp.dll taglib-sharp.dll

iTunesThaiFixed

ยอดเยี่ยม!

Tags: , , ,

Comments

2.
m3rlinez m3rlinez says:

Thanks man! A little too late though Tong

3.
hybridknight hybridknight says:

โชคดีที่ผม google ก่อน

เลยเจอ tag2utf

4.
m3rlinez m3rlinez says:

ทำไมทุกคนหาเจอวะ -_-'

5.
chakrit chakrit says:

+1 - -' why everyone can find it

6.
chingcp26 chingcp26 says:

I can't find it too.  Thank you very much for your code.  It's running perfectly.

7.
เอื้อง เอื้อง says:

มีวิธีแก้ ง่ายกว่าที่อธิบายไหมคะ จะขอรบกวนช่วยอธิบายด้วยคะ ขอบคุณคะ

Add comment


(Will show your Gravatar icon)

biuquote
  • Comment
  • Preview
Loading