تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
إستخراج ال Tags من ملف MP3
#1
كاتب الموضوع : crazy-man


بسم الله الرحمن الرحيم


إستخراج ال Tags من ملف MP3

مقدمة :

درسنا اليوم ليس له علاقة فقط بالفيجوال بيسك دوت نت بل يمكن استغلاله في لغات برمجة اخرى، الدرس سيكون حول كيفية استخراجنا لمعلومات معينة من ملف من نوع MP3. هذا الأمر كنت بحاجة اليه عند عملي لبرنامج من نوع MP3 Player طبعا هناك مكتبات جاهزة تساعدك على ذلك و أيضا أداة ال WMP تمكنك من ذلك لكني كنت أريد أن أعمل الكود الخاص باستخراج تلك المعلومات لأغراض شخصية فمنها اني عندما أريد قراءة تلك المعلومات لا اريد استعمال اداة ال WMP لأنه من اجل استخراجها يجب ان تمرر اسم الملف اليها و ذلك معناه انها تفتح الملف بل و تقرأه لكي تعطيك تلك المعلومات، الحل كما قلت كان بايجاد أداة اخرى لعمل ذلك و فعلا توجد DLL's لعمل ذلك، لكن لما اخاطر باستعمال DLL قد يكون يستعمل طريقة تجعل برنامجي يستهلك ذاكرة اكثر من اللازم، لذا قررت ان اكتب الكود بنفسي خصوصا أني أعرف ان كل تلك المعلومات موجودة في الملف نفسه.



ID3

أول خطوة كانت كيف سأعرف أين توجد تلك المعلومات بالتحديد في الملف ؟؟؟

بعد بحيث لم يستغرف خمس دقائق وجدت ان هذه المعلومات TAGS تكون في آخر الملف و كل تلك المنطقة او كل تلك المعلومات تسمى ID3، بعد بحث آخر :d وجدت مقالة حولها في ال WikiPedia :

http://en.wikipedia.org/wiki/ID3

الذي يهمنا في هذا المقال أن المعلومات التي نريد موجودة في ال 128 بايت الأخيرة من ملف ال MP3 و هي مقسمة كالتالي :

[LTR]

0 -> 3 = "TAG"

3 -> 33 = Title

33 -> 63 = Artist Name

63 -> 93 = Album

93 -> 97 = Year

97 -> 127 = Comments

127 -> 128 = Genre

[/LTR]

طبعا نبدأ من بداية ال Structure و التي تحتل ال 128 بايت الأخير.

الآن بعد ان عرفنا أين نجد المعلومات و ال Structure الخاصة بها أظن انكم متشوفون لكتابة الكود الخاص بكم الذي يقرأ هذه المعلومات، جيد أتمنى ان يعتبر كل واحد منكم هذا كتمرين له و يحاول ان يكتب كود خاص به و لما لا لا يضعه لنا كرد هنا لعله يكون أحسن من طريقتي.



كتابة الكود

الآن من أجل عمل مرتب وجميل سنقوم بإنشاء Structure خاصة بنا وستكون على الشكل التالي :




كود :
Public Structure MP3TAG

Dim Title As String

Dim Artist As String

Dim Album As String

Dim Année As String

Dim Commentaires As String

Dim Genre As String

End Structure
الآن بعد انشاءنا لل Structure الخاصة بنا سوف نقوم بتسجيل طول كل معلومة ال Structure في ملف ال MP3، يعني اسم المغني يحتوي على كم Char ؟ لو عدت معي للأعلى ستجده يبتدأ من البايت 33 الى 63 يعني الطول المخصص له هو 30 بايت .


كود :
TAG = 3 Chars

Title = 30 Chars

Artist = 30 Chars

Album = 30 Chars

Year = 4 Chars

Comment = 30 Chars

Genre = 1 Char
الآن نقوم بتسجيل هذه المعلومات في برنامجنا على شكل Constants و سيكون تعريفها بالشكل التالي :


كود :
Const TitleChars As Integer = 30

Const ArtistChars As Integer = 30

Const AlbumChars As Integer = 30

Const YearChars As Integer = 4

Const CommentsChars As Integer = 30

Const GenreChars As Integer = 1
جميل، لحد الآن كل الأمور واضحة، الآن ننتقل للكود الذي سيمكننا من استخراج هذه المعلومات لأننا لحد الآن لم نعمل سوى بعض التعريفات، نقوم بعمل Function تعيد لنا متغير من نوع MP3TAG وهوال Structure التي عرفناها في الأول و سيكون تعريف الدلة كالتالي :


كود :
Private Function GetMp3Tags(ByVal MP3Path As String) As MP3TAG

End Function
داخل هذا ال Function سنبدأ العمل،

الخطوة الاولى هي فتح الملف بشكل Binary لذا فال StreamReader لن تنفعنا بل سنستعمل بدلها ال BinaryReader، نقوم بتعريفها بالشكل التالي :


كود :
Dim Mp3Binary As New BinaryReader(File.Open("D:\music\Kan Tayeb.mp3", FileMode.Open))
الملاحظة التي يمكن ملاحظتها هي انه لم نمرر للكلاس BinaryReader مسار ملف معين كما نفعل مع ال StreamReader بل استعملنا File.Open() ذلك ا نال BinaryReader يستقبل Stream و ال File.Open() يقوم بقراء ملف و يرجع FileStream و طبعنا حددنا نوع الفتح : FileMode.Open .

الآن لدينا محتوي ملف ال MP3 في الدالة Mp3Binary.

سنقوم الآن باعلان متغير من نوع Char و سيكون بالتحديد Array ذو حجم ال Structure الخاصة بال Tags في ملف ال MP3 و التعريف سيكون كالتالي :


كود :
Dim Tags(125) As Char
الآن سوف ... "هيهووووووووووووووو لحظة لحظة، في البداية قلت ا نال Tags تحتل ال 128 بايت الأخير من الملف لكنك أعلنت Array من 125 فقط ، أين الباقي؟؟؟"

ملاحظة في محلها لكن لو عدت معي الى البداية و ال Structure فسنجد ان كلمة "TAG" تحتل ال 3 Bytes الأولى من ال Structure و نحن فعليا لانحتاجها لذا سوف لن نأخذها في الحسبان لذا سنقرأ فقط 125 بايت، الآن تبين كل شئ، أليس كذلك J.

الخطوة التالية ستكون بأن نضع مؤشرنا على آخر 125 بايت في الملف و حن نعرف ان محتوى الملف الآن موجود في المتغير Mp3Binary و من أجر وضع المؤشر او بتعبير آخر من أجل أن ننتقل الى بداية آخر 125 بايت سيكون الكود كالتالي :


كود :
Mp3Binary.BaseStream.Position = Mp3Binary.BaseStream.Length – 125
الخاصية Position تمكننا من تحديد مكان البداية في Stream معينة و نحن حددنا له ان البداية ستكون طول ال Stream – 125 أظن ان هذه الجملةلا تحتاج لشرح أكثر.

الآن بعد ان انتقلنا الى بداية ال 125 بايت الأخيرة سوف نقوم بقراءتها ووضعها في ال Array التي اعلناها Tags() و الكود هو :


كود :
Mp3Binary.Read(Tags, 0, 125)
دالة Read هنا استقبلت ثلاث Params الأول ال Array التي توضع فيها المعلومات و هذه ال Array يمكن ان تكون من Char كما هو الحل في مثالنا أو Byte ثانيا نقطة بداية القراءة و هي 0 بالطبع و أخيرا كم عدد ال Bytesالتي يجب قراءتها.

الآن بعد ان وضعنا المعلومات التي نريدها في ال Array الخاص بنا فلم نعد نحتاج المتغير Mp3Binary لذا نقوم باغلاقه :


كود :
Mp3Binary.Close()
الآن التعامل مع Array من نوع Char سيكون اكثر تعقيدا لذا من اجل تفادي هذه التعقيدات نحوله الى String :


كود :
Dim TagToString As String = Convert.ToString(Tags)
الآن لدينا TagToString يحتوي على المعلومات الخاصة بملف ال MP3 ك String

الآن يسهل لدينا قراءة المعلومات و استخراج ما نريد.

كود الاستخراج من ال String سيكون كالتالي :


كود :
'Get Title

GetMp3Tags.Title = TagToString.Substring(0, TitleChars)

'Get Artist

GetMp3Tags.Artist = TagToString.Substring(TitleChars, ArtistChars)

'Get Album

GetMp3Tags.Album = TagToString.Substring(TitleChars + ArtistChars, AlbumChars)

'Get Year

GetMp3Tags.Year = TagToString.Substring(TitleChars + ArtistChars + AlbumChars, YearChars)

'Get Comments

GetMp3Tags.Comments = TagToString.Substring(TitleChars + ArtistChars + AlbumChars + YearChars, CommentsChars)

'Get Genre

GetMp3Tags.Genre = TagToString.Substring(TitleChars + ArtistChars + AlbumChars + YearChars + CommentsChars, GenreChars)
لنأخذ مثالا السطر الأول الذي يقوم باستخراج اسم المغني :


كود :
GetMp3Tags.Title = TagToString.Substring(0, TitleChars)
بكل بساطة أسندنا للمتغير Title والذي هو ضمن ال Structure المسماة GetMp3Tags اسم المقطع عن طريق استعمال SubString في ال String التي تحتوي على كل المعلومات و طبعا أخذنا اسم المقطع من الحرف الأول الى الحرف رقم 30 و هوالمحدد في ال Constant المسماة TitleChars،

بعدها سنأخذ اسم المغني و ستكون بدايته من الحرف 30 الى الحرف 60 :


كود :
GetMp3Tags.Artist = TagToString.Substring(TitleChars, ArtistChars)
بالنسبة لاسم ال Album ستكون بدايته هي بداية طول اسم المقطع + اسم المغني : TitleChars + ArtistChars و طوله طبعا هو قيمة الثابث AlbumChars :


كود :
GetMp3Tags.Album = TagToString.Substring(TitleChars + ArtistChars, AlbumChars)
نفس الأمر بالنسبة للمعلومات الأخرى دائما نبدأ بمجموع طول ال Tags السابقة وبهذا سنحصل على ما نريد.



الكود الكامل

الآن اليكم الكود كاملا و يمكنكم تجربته :


كود :
Imports System.IO

Public Class Form1



Public Structure MP3TAG

Dim Title As String

Dim Artist As String

Dim Album As String

Dim Year As String

Dim Comments As String

Dim Genre As String

End Structure



Const TitleChars As Integer = 30

Const ArtistChars As Integer = 30

Const AlbumChars As Integer = 30

Const YearChars As Integer = 4

Const CommentsChars As Integer = 30

Const GenreChars As Integer = 1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim FormattedString As String = ""

Dim MyMP3Tags As MP3TAG

MyMP3Tags = GetMp3Tags("d:\music\el-lilady.mp3")

With MyMP3Tags

MessageBox.Show("Title : " & .Title)

MessageBox.Show("Artist : " & .Artist)

MessageBox.Show("Album : " & .Album)

MessageBox.Show("Year : " & .Year)

MessageBox.Show("Comments : " & .Comments)

MessageBox.Show("Genre : " & .Genre)



End With

End Sub



Private Function GetMp3Tags(ByVal MP3Path As String) As MP3TAG



Dim Mp3Binary As New BinaryReader(File.Open("D:\music\Kan Tayeb.mp3", FileMode.Open))



Dim Tags(125) As Char

Mp3Binary.BaseStream.Position = Mp3Binary.BaseStream.Length - 125

Mp3Binary.Read(Tags, 0, 125)

Mp3Binary.Close()

Dim TagToString As String = Convert.ToString(Tags)



'Get Title

GetMp3Tags.Title = TagToString.Substring(0, TitleChars)

'Get Artist

GetMp3Tags.Artist = TagToString.Substring(TitleChars, ArtistChars)

'Get Album

GetMp3Tags.Album = TagToString.Substring(TitleChars + ArtistChars, AlbumChars)

'Get Year

GetMp3Tags.Year = TagToString.Substring(TitleChars + ArtistChars + AlbumChars, YearChars)

'Get Comments

GetMp3Tags.Comments = TagToString.Substring(TitleChars + ArtistChars + AlbumChars + YearChars, CommentsChars)

'Get Genre

GetMp3Tags.Genre = TagToString.Substring(TitleChars + ArtistChars + AlbumChars + YearChars + CommentsChars, GenreChars)





Return GetMp3Tags

End Function





End Class
}}}}
تم الشكر بواسطة:


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم