02-10-12, 12:35 AM
كاتب الموضوع : 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
كود :
TAG = 3 Chars
Title = 30 Chars
Artist = 30 Chars
Album = 30 Chars
Year = 4 Chars
Comment = 30 Chars
Genre = 1 Char
كود :
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 Function GetMp3Tags(ByVal MP3Path As String) As MP3TAG
End Function
الخطوة الاولى هي فتح الملف بشكل Binary لذا فال StreamReader لن تنفعنا بل سنستعمل بدلها ال BinaryReader، نقوم بتعريفها بالشكل التالي :
كود :
Dim Mp3Binary As New BinaryReader(File.Open("D:\music\Kan Tayeb.mp3", FileMode.Open))
الآن لدينا محتوي ملف ال MP3 في الدالة Mp3Binary.
سنقوم الآن باعلان متغير من نوع Char و سيكون بالتحديد Array ذو حجم ال Structure الخاصة بال Tags في ملف ال MP3 و التعريف سيكون كالتالي :
كود :
Dim Tags(125) As Char
ملاحظة في محلها لكن لو عدت معي الى البداية و ال Structure فسنجد ان كلمة "TAG" تحتل ال 3 Bytes الأولى من ال Structure و نحن فعليا لانحتاجها لذا سوف لن نأخذها في الحسبان لذا سنقرأ فقط 125 بايت، الآن تبين كل شئ، أليس كذلك J.
الخطوة التالية ستكون بأن نضع مؤشرنا على آخر 125 بايت في الملف و حن نعرف ان محتوى الملف الآن موجود في المتغير Mp3Binary و من أجر وضع المؤشر او بتعبير آخر من أجل أن ننتقل الى بداية آخر 125 بايت سيكون الكود كالتالي :
كود :
Mp3Binary.BaseStream.Position = Mp3Binary.BaseStream.Length – 125
الآن بعد ان انتقلنا الى بداية ال 125 بايت الأخيرة سوف نقوم بقراءتها ووضعها في ال Array التي اعلناها Tags() و الكود هو :
كود :
Mp3Binary.Read(Tags, 0, 125)
الآن بعد ان وضعنا المعلومات التي نريدها في ال Array الخاص بنا فلم نعد نحتاج المتغير Mp3Binary لذا نقوم باغلاقه :
كود :
Mp3Binary.Close()
كود :
Dim TagToString As String = Convert.ToString(Tags)
الآن يسهل لدينا قراءة المعلومات و استخراج ما نريد.
كود الاستخراج من ال 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)
بعدها سنأخذ اسم المغني و ستكون بدايته من الحرف 30 الى الحرف 60 :
كود :
GetMp3Tags.Artist = TagToString.Substring(TitleChars, ArtistChars)
كود :
GetMp3Tags.Album = TagToString.Substring(TitleChars + ArtistChars, AlbumChars)
الكود الكامل
الآن اليكم الكود كاملا و يمكنكم تجربته :
كود :
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