Home > C#, Database > Playing MP3 from C#

Playing MP3 from C#

After handling a huge collections of MP3 files, one in my back-up drive and another in my hard-disk’s library, It meant huge gobbling up so much space, which of course you realize when your external hard-drive shows up “Drive Full” message. And an idea bloomed to create this mp3 player which plays files stored in my database!

I have named it “Byte Player” and according to the name the application would be playing the music when data is fed into as byte arrays. The database is designed using the same strategy that’s designed to store normal files.

Add the following DLL reference: “irrKlang.NET4” and put the following DLLs to your bin folder:
~ ikpFlac.dll
~ ikpMP3.dll
~ irrKlang.NET4.dll

Use the following reference:

using IrrKlang;

Generated Database Script to Create Table:

CREATE TABLE [dbo].[MusicLibrary](
	[FileID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
	[FileName] [nvarchar](50) NOT NULL,
	[FileContent] [varbinary](max) NOT NULL,
	[FileType] [nvarchar](50) NOT NULL,
	[CreateBy] [nvarchar](128) NULL,
	[CreatedOn] [datetime] NULL,
	[ModifiedBy] [nvarchar](128) NULL,
	[ModifiedOn] [datetime] NULL,
 CONSTRAINT [PK_MusicLibrary] PRIMARY KEY CLUSTERED 
(
	[FileID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[MusicLibrary] ADD  CONSTRAINT [DF_MusicLibrary_FileID]  DEFAULT (newid()) FOR [FileID]
GO

ALTER TABLE [dbo].[MusicLibrary] ADD  CONSTRAINT [DF_MusicLibrary_CreateBy]  DEFAULT (user_name(user_id(user_name()))) FOR [CreateBy]
GO

ALTER TABLE [dbo].[MusicLibrary] ADD  CONSTRAINT [DF_MusicLibrary_CreatedOn]  DEFAULT (getdate()) FOR [CreatedOn]
GO

ALTER TABLE [dbo].[MusicLibrary] ADD  CONSTRAINT [DF_MusicLibrary_ModifiedBy]  DEFAULT (user_name(user_id(user_name()))) FOR [ModifiedBy]
GO

ALTER TABLE [dbo].[MusicLibrary] ADD  CONSTRAINT [DF_MusicLibrary_ModifiedOn]  DEFAULT (getdate()) FOR [ModifiedOn]
GO

The C# application will hold the following methods to interact with the database.

const string connectionString = @"Server=KRISHNA\SQLEXPRESS;Database=music;Trusted_Connection=True;";

/// <summary>
/// Function to select files from the computer to be saved in the database.
/// </summary>
private void OpenMP3Files()
{
    OpenFileDialog dialog = new OpenFileDialog();
    dialog.Filter = "MP3 files|*.mp3";
    dialog.FilterIndex = 1;
    dialog.InitialDirectory = @"C:\\";
    dialog.RestoreDirectory = true;
    dialog.CheckFileExists = true;
    dialog.CheckPathExists = true;
    dialog.Multiselect = true;
    if (dialog.ShowDialog() == DialogResult.OK)
    {
        Cursor.Current = Cursors.WaitCursor;
        foreach (string filename in dialog.FileNames)
        {
            FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read);
            using (BinaryReader reader = new BinaryReader(stream))
            {
                long length = new FileInfo(filename).Length;
                InsertMP3File(Path.GetFileName(filename), reader.ReadBytes((int)length));
            }
        }
        GetAllMP3();
    }
}

/// <summary>
/// Retrieves entire MP3 list from database (excludes the file content)
/// </summary>
private void GetAllMP3()
{
    string queryString = "SELECT [FileID], [FileName] FROM [MusicLibrary]";
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = new SqlCommand(queryString, connection);
        DataSet dataset = new DataSet();
        adapter.Fill(dataset);
        if (dataset.Tables.Count > 0)
        {
            gridMusic.DataSource = dataset.Tables[0];
            gridMusic.Columns[0].Visible = false;
            gridMusic.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }
    }
}

/// <summary>
/// Individual files are stored in the database.
/// </summary>
/// <param name="filename"></param>
/// <param name="data"></param>
private void InsertMP3File(string filename, byte[] data)
{
    string filetype = @"audio / mpeg";
    string queryString = "INSERT INTO [MusicLibrary] ([FileName] ,[FileContent] ,[FileType]) VALUES (@FileName, @FileContent, @FileType)";
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new SqlCommand(queryString, connection);
        command.Parameters.Add(new SqlParameter("@FileName", (object)filename));
        command.Parameters.Add(new SqlParameter("@FileContent", (object)data));
        command.Parameters.Add(new SqlParameter("@FileType", (object)filetype));
        command.Connection.Open();
        command.ExecuteNonQuery();
        command.Connection.Close();
    }
}

Inorder to play the MP3 file I had some initial consideration and based on some strong reviews started of with the “NAudio” library [Ref: http://naudio.codeplex.com] but i faced some issues while trying to play the file from stream and upon searching through discussion forums I discovered that these issues are currently being worked upon and would have a fix in future releases; Therefore i was forced to consider my second choice “irrKlang” sound library [Ref: http://www.ambiera.com/irrklang/] and it worked out to be more simple and brilliant! The code illustrated below shows the fine integration between this library api and the database.

const string sound = "static.mp3";
ISoundEngine engine = new ISoundEngine();

/// <summary>
/// Retrieve individual file content from database
/// </summary>
/// <param name="fileID"></param>
private void GetMP3Data(string fileID)
{
    string queryString = "SELECT [FileContent] FROM [MusicLibrary] WHERE [FileID] = @FileID";
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new System.Data.SqlClient.SqlCommand(queryString, connection);
        command.Parameters.Add(new SqlParameter("@FileID", (object)fileID));
        command.Connection.Open();
        byte[] buffer = (byte[])command.ExecuteScalar();
        if (engine.IsCurrentlyPlaying(sound))
        {
            engine.RemoveAllSoundSources();
        }
        PlayMP3(buffer, sound);
        command.Connection.Close();
    }
}

/// <summary>
/// Play a single MP3 file
/// </summary>
/// <param name="data"></param>
/// <param name="filename"></param>
private void PlayMP3(byte[] data, string filename)
{
    ISoundSource source = engine.AddSoundSourceFromMemory(data, filename);
    engine.Play2D(filename);
}

I am so much interested in improving this and building a full-fledged player that would support right from ripping CD’s and expanding the database to include more information about the music albums and MP3 tags.

Advertisements
Categories: C#, Database Tags: , , , ,
  1. March 2, 2011 at 8:18 AM

    Awe-sum post. Your concept is very good. I will also try to make one like yours.
    🙂

  2. Unsesanashy
    March 12, 2011 at 10:48 AM

    The best KB article that I ever read! Good one!

  3. miczoorrutt
    March 16, 2011 at 6:06 PM

    fantastic and this was the one i was looking for!

  4. Mohan
    March 21, 2011 at 1:47 PM

    nice stuff! nice thought and works when tried this code piece;

  5. August 12, 2011 at 12:32 PM

    Definitely, what a fantastic blog and illuminating posts, I definitely will bookmark your site.All the Best!

  6. Avinash
    August 14, 2011 at 6:40 AM

    Hi
    I have tried the above code and was able to save it to the data base but could not play it on my windows form.Please Help.

    • Balaji Baskar
      August 17, 2011 at 8:45 PM

      Avinash, I would be happy to help you out; from reading through your comment I see that you are able to save the file in database, so that assures we have crossed half the work, Now can you confirm if you are able to read the file from the database? Debug GetMP3Data() function to check this. Also when this is done check PlayMP3() function. Also if you would have missed this, download the “irrKlang” library from the following location: http://www.ambiera.com/irrklang/downloads.html
      I hope this helps!

  7. August 17, 2011 at 5:28 AM

    Thanks for the informative article, it was a good read and I hope its ok that I share this with some facebook friends. Thanks.

  8. Avinash
    August 17, 2011 at 11:40 PM

    private void GetAllMP3()

    {
    string connectionString = “Data Source=.\\SQLEXPRESS;AttachDbFilename=c:\\users\\avinash\\documents\\visual studio 2010\\Projects\\WindowsFormsApplication2\\WindowsFormsApplication2\\Database1.mdf;Integrate” +
    “d Security=True;User Instance=True”;
    string queryString = “SELECT [music_filename], [music_filepath] FROM [music_details]”;

    using (SqlConnection connection = new SqlConnection(connectionString))

    {

    SqlDataAdapter adapter = new SqlDataAdapter();

    adapter.SelectCommand = new SqlCommand(queryString, connection);

    Database1DataSet dataset = new Database1DataSet ();

    adapter.Fill(dataset);
    string a= gridMusic.CurrentCell.Value.ToString();
    GetMP3Data(a);
    }

    }

    const string sound = “static.mp3”;

    ISoundEngine engine = new ISoundEngine();
    private void GetMP3Data(string file_name)

    {

    string queryString = “SELECT [music_file] FROM [music_details] WHERE [music_filename] = @music_filename”;
    string connectionString = “Data Source=.\\SQLEXPRESS;AttachDbFilename=c:\\users\\avinash\\documents\\visual studio 2010\\Projects\\WindowsFormsApplication2\\WindowsFormsApplication2\\Database1.mdf;Integrate” +
    “d Security=True;User Instance=True”;
    using (SqlConnection connection = new SqlConnection(connectionString))

    {

    SqlCommand command = new System.Data.SqlClient.SqlCommand(queryString, connection);

    command.Parameters.Add(new SqlParameter(“@music_filename”, (object)file_name));

    command.Connection.Open();

    byte[] buffer = (byte[])command.ExecuteScalar();

    if (engine.IsCurrentlyPlaying(sound))
    {

    engine.RemoveAllSoundSources();

    }

    PlayMP3(buffer, sound);

    command.Connection.Close();

    }

    }
    private void PlayMP3(byte[] data, string filename) reply
    {

    ISoundSource source = engine.AddSoundSourceFromMemory(data, filename);
    engine.SoundVolume = 100;
    engine.Play2D(filename);
    }
    Thank You for your last
    This is the code that I used.Please check it if i missed out anything in this and I have included the irrklang library.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: