Online courses in ASP.NET MVC / Core, jQuery, Angular, and Design Patterns conducted by Bipin Joshi. Read more...
Learn ASP.NET MVC / Core, jQuery, Angular, and Design Patterns through our online training programs. Courses conducted by Bipin Joshi on weekends. Read more details here.

Untitled 1

Display a list of audio / video files using HTML5 and GridView

Recently one of the readers asked this question - How to display a list of audio and video files in ASP.NET web form? Additional requirements were as follows:

  • The database contains audio as well as video file URLs. At run time depending on whether a file is audio file or video file appropriate media player should be displayed to the user.
  • At a time only one media file should be playing from a given list.

This post provides one of the possible solution to the problem. Using the solution provided in this post you can display a list of audio and video files in a GirdView control as shown below:

Let's begin our development. First of all, create a new ASP.NET Web Forms project using Visual Studio. Then add a new SQL Server database in the project (or you may create it in a stand alone SQL Server installation) and name it as AudioVideoDb. The AudioVideoDb database contains a single table - AudioVideo - with the following schema:

As you can see the AudioVideo table has four columns viz. Id, Title, Description and Url. The column names are self-explanatory. The Url column will store links to the audio or video files. To make them easy to use with ASP.NET you will store the links in this form:

~/media/audio1.mp3
~/media/video1.mp4

Next, add a few test records in the database and also make sure that you have the audio / video files in some folder of your web application (say Media folder).

Now add a new web form in the project and place a GridView control on the web form. The GridView control will have three columns as shown below:

As you can see the Title and Description columns are of type BoundField and Audio / Video column is of type TemplateField. Set the HeaderText and DataField property of Title column to Title. Similarly, set the HeaderText and DataField property of Description column to Description. Switch to the template editor of the Audio / Video column and place a Literal control in the ItemTemplate.

We use Literal control here because we wish to render either an audio player or video player dynamically based on the media file extension. This can be done by programmatically assign the required HTML markup to the Literal control. Make sure to data bind the Literal control with the Url column of the table:

<asp:TemplateField HeaderText="Audio / Video">
    <ItemTemplate>
        <asp:Literal ID="Literal1" runat="server" 
             Text='<%# Page.ResolveClientUrl(Eval("Url").ToString()) %>'></asp:Literal>
    </ItemTemplate>
    <ItemStyle VerticalAlign="Top" Width="300px" />
</asp:TemplateField>

Notice the above markup carefully. The AudioVideo table stores links prefixed with "~/". The client browser won't understand this URL unless you convert it into a form that is usable from the client end. This is done with the help of Page.ResolveClientUrl() method.

Now add a new Entity Framework data model in the application and configure it to use AudioVideo table of the AudioVidedDb that you created earlier. The following figure shows the data model class for the AudioVideo table:

Next, go in the code behind file of the web form and write a method - SelectAll - as shown below:

public List<AudioVideo> SelectAll()
{
    AudioVideoDbEntities db=new AudioVideoDbEntities();
    var data = from i in db.AudioVideos
                select i;
    return data.ToList();
}

The SelectAll() method simply returns all the records from the AudioVideo table and supplies data to the GridView. Go to the properties of GridView and set the SelectMethod property to SelectAll. This way GridView is bound with the audio/video data returned by the SelectAll() method.

Now comes the important part - dynamically rendering an audio player or a video player. To accomplish this task you will use RowDataBound event of the GridView. Inside the RowDataBound event handler you will check the file extension of the media file and accordingly render HTML5 <audio> element or <video> element. The following code shows the complete RowDataBound event handler:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        Literal media = (Literal)e.Row.Cells[1].FindControl("Literal1");
        string mediaId = "media-" + media.UniqueID;
        string str = "";
                
        if (media.Text.EndsWith(".mp4"))
        {
            str = "<video src='" + media.Text + "' controls='controls' id='" + mediaId  + "' />";
        }
        else
        {
            str = "<audio src='" + media.Text + "' controls='controls' id='" + mediaId + "' />";
        }
        media.Text = str;
    }
}

The RowDataBound event is raised for all the rows of a GridView including header and footer. We are interested only in the data rows and hence the code first checks the RowType of the current row. Inside the if block you get hold of the Literal control using the FindControl() method. The file extension is then checked. In this example you check only two file extensions - mp3 for audio files and mp4 for video files. However, you can easily perform additional checks here. Depending on the file type HTML5 <audio> or <video> elements are emitted dynamically. Recollect that the Literal control is bound with the Url column and will contain link to the media file. The src attribute of <audio> or <video> tag is set to this Url. Setting the controls attribute of <audio> and <video> displays buttons such as play, pause and volume. Each <audio> and <video> element you emit dynamically need to have a unique ID because you will need to access them from the client side code. This can be done by setting the id attribute to a unique ID generated based on the UniqueID property of the Literal control. Finally, the Text property of the Literal control is set to the <audio> or <video> element markup.

This completes the server side coding. You can run the web form and play media files at this stage also. However, you will observe that at a time you can play multiple media files. That means at a time the end user can listen to multiple audio streams unless he pauses / stops the previous file. This might be undesirable. Luckily, you can throw in a little jQuery code and ensure that only one media file is playing at a time. Let's see how to do that.

Switch to the markup view of the web form and add a <script> reference to jQuery library (You may need to copy jQuery library into the project or refer it from CDN).

<script src="Scripts/jquery-1.7.2.min.js"></script>

Then add a script block as shown below:

<script type="text/javascript">
    $(document).ready(function () {
        $("video").bind("play", OnVideoPlay);
        $("audio").bind("play", OnAudioPlay);
    });

    function OnAudioPlay(evt) {
        var a = $("audio[id!='" + evt.target.id + "']").get();
        for (var i = 0; i < a.length; i++) {
            a[i].pause();
        }
            
    }

    function OnVideoPlay(evt) {
        var v = $("video[id!='" + evt.target.id + "']").get();
        for (var i = 0; i < v.length; i++) {
            v[i].pause();
        }
    }
</script>

 The ready() function binds client side event handlers for play event of the HTML5 <audio> and <video> elements. Both the event handler functions - OnAudioPlay() and OnVideoPlay() - are quite similar. They essentially filter all the <audio> or <video> elements except the one that is currently being played. This is done using the attribute selectors:

$("audio[id!='" + evt.target.id + "']")
$("video[id!='" + evt.target.id + "']")

The get() method returns the original DOM elements and the returned elements are stored in an array. A for loop iterates through this array and calls the pause() method on individual <audio> or <video> element. This way the audio / video is paused.

That's it! You can run the web form and now only the last audio or video you played will run and previously running audios / videos (if any) will be paused.

 

 

 




Bipin Joshi is a software consultant, trainer, author and a yogi having 21+ years of experience in software development. He conducts online courses in ASP.NET MVC / Core, jQuery, AngularJS, and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced Yoga way of life he also teaches Ajapa Meditation to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 02 Apr 2013



Tags : ASP.NET Web Forms jQuery HTML5