Accessing the Media API in .NET

This topic describes how to access the Brightcove Media API using C# .NET 3.5. Usage of another .NET programming language can be extrapolated by principle. For a. NET SDK that provides more complete access to the Media API, including write methods, see Sukiyoshi, developed and maintained by Mark Stiles at Oasis Technology Partners in Boston. For a list of SDKs for other languages, see The Video Cloud SDKs.

Before you begin

The basics of what the Media API is and how it works are covered in the Media API Getting Started topic in the Video Cloud documentation. If you haven't already, read that before continuing here.

This document also assumes you're well-versed in .NET — creating and importing classes, and so forth.

To prevent unauthorized access to the metadata in your account, access to the API is protected with tokens that you pass as a parameter when making API calls. Like other web-based APIs, tokens are generated for you by Brightcove and protected by you. The first thing you need to do to get started with development is to get your Media API tokens.

JSON in .NET?

There is no standard .NET library for parsing JSON, so we'll be using one of many open source libraries that are available. This particular one is from NewtonSoft. You can find the Library and source here.

Start a new .NET project called BrightcoveAPI and make sure you include a reference to the Newtonsoft.JSON library. The first thing we're going to do is create a static class that will contain the configuration items for the Media API. We'll call this class BCAPIConfig:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace BrightcoveAPI
{
    public static class BCAPIConfig
    {
        public static String ReadToken = "0Z2dtxTdJAxtbZ-d0U7Bhio2V1Rhr5Iafl5FFtDPY8E";
        public static String WriteToken = "your-write-token-here";
        public static String ServiceURL = "http://api.brightcove.com/services/library";
    }
}

Now we'll create a base class to handle the generic REST API requests, so add a class to the project we'll call BCAPIRequest.

using System;
using System.Collections.Generic;
using System.IO;
using System.Net; 
using System.Text;
using System.Web;
using Newtonsoft.Json;
 
namespace BrightcoveAPI
{
    public class BCAPIRequest
    {
        private HttpWebRequest webRequest;
 
        public JsonReader Execute( Dictionary<String,String> reqParams )
        {
            String reqUrl = BCAPIConfig.ServiceURL + "?";
            int i = 0;
            foreach (String key in reqParams.Keys)
            {
                if (i > 0) reqUrl += "&";
                reqUrl += String.Format("{0}={1}", key, HttpUtility.UrlEncode(reqParams[key]));
                i++;
            }
            webRequest = WebRequest.Create(reqUrl) as HttpWebRequest;
            HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse;
            TextReader textreader = new StreamReader(response.GetResponseStream());
            JsonReader reader = new JsonTextReader(textreader);
            return reader;
        }
 
    }
}

Nothing extraordinary here: we just create a generic class that creates the webRequest and joins all the parameters passed in a standard .NET Dictionary into a URLEncoded string to be added to the API URL defined in the BCAPIConfig static class. The result is then passed as a JSON Reader class (not unlike a .NET Stream) to the caller.

Parsing the returned JSON Data

There are many ways to parse the returned JSON data, but to make the code as reusable as possible, let's create a Brightcove Object base class that contains all necessary conversion functions from and to JSON data formats, in particular for converting DateTime values:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace BrightcoveAPI
{
    public class BCObject
    {
        
        protected DateTime DateFromUnix(object value)
        {
            long millisecs = long.Parse(value.ToString());
            double secs = millisecs / 1000;
            return new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(secs);
        }
    }
}

Then we can derive classes for each Brightcove Media API Data type. For example, the Video class can look something like this:

using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Newtonsoft.Json;
 
namespace BrightcoveAPI
{
    public enum BCVideoEconomics { FREE, AD_SUPPORTED };
    
    // <summary>
    // The Video object is an aggregation of metadata and asset information associated with a video
    // </summary>
    public class BCVideo : BCObject
    {
        private long _id;
        private DateTime _creationDate;
        private DateTime _publishedDate;
        private DateTime _lastModifiedDate;
        private long _length;
        private int _playsTotal;
        private int _playsTrailingWeek;
        
        // <summary>
        // A number that uniquely identifies this Video, assigned by Brightcove when the Video is created.
        // </summary>
        public long id { get { return _id; } }
 
        // <summary>
        // The title of this Video.
        // </summary> 
        public String name { get; set; }
 
        // <summary>
        // A short description describing this Video, limited to 256 characters.
        // </summary> 
        public String shortDescription { get; set; }
 
        // <summary>
        // A longer description of this Video, bounded by a 1024 character limit.
        // </summary> 
        public String longDescription { get; set; }
 
        // <summary>
        // The date this Video was created, represented as the number of milliseconds since the Unix epoch.
        // </summary> 
        public DateTime creationDate { get { return _creationDate; } }
 
        // <summary>
        // The date this Video was last made active, represented as the number of milliseconds since the Unix epoch.
        // </summary> 
        public DateTime publishedDate { get { return _publishedDate; } }
 
        // <summary>
        // The date this Video was last modified, represented as the number of milliseconds since the Unix epoch.
        // </summary> 
        public DateTime lastModifiedDate { get { return _lastModifiedDate; } }
 
        // <summary>
        // An optional URL to a related item.
        // </summary> 
        public String linkURL { get; set; }
 
        // <summary>
        // The text displayed for the linkURL.
        // </summary> 
        public String linkText { get; set; }
 
        // <summary>
        // A list of Strings representing the tags assigned to this Video.
        // </summary> 
        public List<String> tags = new List<string>();
 
        // <summary>
        // The URL to the video still image associated with this Video. Video stills are 480x360 pixels.
        // </summary> 
        public String videoStillURL { get; set; }
 
        // <summary>
        // The URL to the thumbnail image associated with this Video. Thumbnails are 120x90 pixels.
        // </summary> 
        public String thumbnailURL { get; set; }
 
        // <summary>
        // A user-specified id that uniquely identifies this Video. ReferenceID can be used as a foreign-key to identify this video in another system. 
        // </summary> 
        public String referenceId { get; set; }
 
        // <summary>
        // The length of this video in milliseconds.
        // </summary> 
        public long length { get { return _length; } }
 
        // <summary>
        // Either FREE or AD_SUPPORTED. AD_SUPPORTED means that ad requests are enabled for this Video.
        // </summary> 
        public BCVideoEconomics economics { get; set; }
 
        // <summary>
        // How many times this Video has been played since its creation.
        // </summary> 
        public int playsTotal { get { return _playsTotal; } }
 
        // <summary>
        // How many times this Video has been played within the past seven days, exclusive of today.
        // </summary> 
        public int playsTrailingWeek { get { return _playsTrailingWeek; } }
 
        // <summary>
        // Constructor, getting a JSON Reader passed for initialization
        // </summary> 
        public BCVideo(JsonReader reader)
        {
            reader.Read();
            while (reader.TokenType != JsonToken.EndObject)
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
 
                    switch (reader.Value.ToString())
                    {
                        case "error":
                            reader.Read();
                            Console.WriteLine(String.Format("Error: {0}", reader.Value));
                            break;
 
                        case "id":
                            reader.Read();
                            _id = (long)reader.Value;
                            break;
 
                        case "name":
                            reader.Read();
                            name = (string)reader.Value;
                            break;
 
                        case "shortDescription":
                            reader.Read();
                            shortDescription = (string)reader.Value;
                            break;
 
                        case "longDescription":
                            reader.Read();
                            longDescription = (string)reader.Value;
                            break;
 
                        case "creationDate":
                            reader.Read();
                            _creationDate = DateFromUnix(reader.Value);
                            break;
 
                        case "publishedDate":
                            reader.Read();
                            _publishedDate = DateFromUnix(reader.Value);
                            break;
 
                        case "lastModifiedDate":
                            reader.Read();
                            _lastModifiedDate = DateFromUnix(reader.Value);
                            break;
 
                        case "linkURL":
                            reader.Read();
                            linkURL = (string)reader.Value;
                            break;
 
                        case "linkText":
                            reader.Read();
                            linkText = (string)reader.Value;
                            break;
 
                        case "tags":
                            reader.Read();
                            tags.Clear();
                            if (reader.Value != null)
                            {
                                String[] ltags = reader.Value.ToString().Split(',');
                                foreach (String stag in ltags) tags.Add(stag);
                            }
                            break;
 
                        case "videoStillURL":
                            reader.Read();
                            videoStillURL = (string)reader.Value;
                            break;
 
                        case "thumbnailURL":
                            reader.Read();
                            thumbnailURL = (string)reader.Value;
                            break;
 
                        case "referenceId":
                            reader.Read();
                            referenceId = (string)reader.Value;
                            break;
 
                        case "length":
                            reader.Read();
                            _length = (long)reader.Value;
                            break;
 
                        case "economics":
                            reader.Read();
                            economics = (BCVideoEconomics)Enum.Parse(typeof(BCVideoEconomics), reader.Value.ToString());
                            break;
 
                        case "playsTotal":
                            reader.Read();
                            _playsTotal = int.Parse(reader.Value.ToString());
                            break;
 
                        case "playsTrailingWeek":
                            reader.Read();
                            _playsTrailingWeek = int.Parse(reader.Value.ToString());
                            break;
 
                        default:
                            reader.Read();
                            break;
                    }
                }
                reader.Read();
            }
            reader.Read();
        }
    }
}

Basically, what this code does is read a property entry from the JSON stream and sets the value of the associated object property. It's quite a bit of code for such a simple operation, but we only need to define this once.

Putting it all together

Great, now we have all the building blocks, let's implement the API. As example, we'll use the Video Read API again. If you look at the available functions, you'll see that the calls either return one video object, or an array of video objects. Let's do an example of both:

using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Newtonsoft.Json;
 
namespace BrightcoveAPI
{
    public static class BCAPI
    {
        public static List<BCVideo> FindAllVideos(int pageSize, int pageNumber,
            BCSortByType sortBy, BCSortOrderType sortOrder, List<String>fields, Boolean getItemCount)
        {
            List<BCVideo> videos = new List<BCVideo>();
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
            //Build the REST parameter list
            reqparams.Add("command", "find_all_videos");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("get_item_count", getItemCount.ToString().ToLower());
            if (fields != null) reqparams.Add("fields", Implode(fields));
            reqparams.Add("sort_order", sortOrder.ToString());
            reqparams.Add("sort_by", sortBy.ToString());
            if (pageNumber >= 0) reqparams.Add("page_number", pageNumber.ToString());
            if (pageSize >= 0) reqparams.Add("page_size", pageSize.ToString());
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static List<BCVideo> FindVideosByUserId(String userId, int pageSize,
             int pageNumber, BCSortByType sortBy, BCSortOrderType sortOrder,
             List<String> fields, Boolean getItemCount)
        {
            List<BCVideo> videos = new List<BCVideo>();
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
            reqparams.Add("command", "find_videos_by_user_id");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("user_id", userId);
            reqparams.Add("get_item_count", getItemCount.ToString().ToLower());
            if (fields != null) reqparams.Add("fields", Implode(fields));
            reqparams.Add("sort_order", sortOrder.ToString());
            reqparams.Add("sort_by", sortBy.ToString());
            if (pageNumber >= 0) reqparams.Add("page_number", pageNumber.ToString());
            if (pageSize >= 0) reqparams.Add("page_size", pageSize.ToString());
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
 
        public static List<BCVideo> FindVideosByCampaignId(long campaignId, int pageSize,
             int pageNumber, BCSortByType sortBy, BCSortOrderType sortOrder,
             List<String> fields, Boolean getItemCount)
        {
            List<BCVideo> videos = new List<BCVideo>();
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
            reqparams.Add("command", "find_videos_by_campaign_id");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("campaign_id", campaignId.ToString());
            reqparams.Add("get_item_count", getItemCount.ToString().ToLower());
            if (fields != null) reqparams.Add("fields", Implode(fields));
            reqparams.Add("sort_order", sortOrder.ToString());
            reqparams.Add("sort_by", sortBy.ToString());
            if (pageNumber >= 0) reqparams.Add("page_number", pageNumber.ToString());
            if (pageSize >= 0) reqparams.Add("page_size", pageSize.ToString());
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static List<BCVideo> FindVideosByText(String text, int pageSize,
            int pageNumber, BCSortByType sortBy, BCSortOrderType sortOrder,
            List<String> fields, Boolean getItemCount)
        {
            List<BCVideo> videos = new List<BCVideo>();
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
            reqparams.Add("command", "find_videos_by_text");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("text", text);
            reqparams.Add("get_item_count", getItemCount.ToString().ToLower());
            if (fields != null) reqparams.Add("fields", Implode(fields));
            reqparams.Add("sort_order", sortOrder.ToString());
            reqparams.Add("sort_by", sortBy.ToString());
            if (pageNumber >= 0) reqparams.Add("page_number", pageNumber.ToString());
            if (pageSize >= 0) reqparams.Add("page_size", pageSize.ToString());
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static List<BCVideo> FindVideosByTags(String and_tags, String or_tags)
        {
            return FindVideosByTags(and_tags, or_tags, -1, -1, BCSortByType.CREATION_DATE,
                 BCSortOrderType.ASC, null, false);
        }
 
        public static List<BCVideo> FindVideosByTags(String and_tags, String or_tags,
             int pageSize, int pageNumber)
        {
            return FindVideosByTags(and_tags, or_tags, pageSize, pageNumber,
                   BCSortByType.CREATION_DATE, BCSortOrderType.ASC, null, false);
        }
 
        public static List<BCVideo> FindVideosByTags(String and_tags, String or_tags,
             int pageSize, int pageNumber, BCSortByType sortBy, BCSortOrderType sortOrder)
        {
            return FindVideosByTags(and_tags, or_tags, pageSize, pageNumber, sortBy, sortOrder, null, false);
        }
 
        public static List<BCVideo> FindVideosByTags(String and_tags, String or_tags,
              int pageSize, int pageNumber, BCSortByType sortBy,
              BCSortOrderType sortOrder, List<String> fields)
        {
            return FindVideosByTags(and_tags, or_tags, pageSize, pageNumber, sortBy, sortOrder, fields, false);
        }
 
        public static List<BCVideo> FindVideosByTags(String and_tags, String or_tags,
             int pageSize, int pageNumber, BCSortByType sortBy, BCSortOrderType sortOrder,
             List<String> fields, Boolean getItemCount)
        {
            List<BCVideo> videos = new List<BCVideo>();
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
            reqparams.Add("command", "find_videos_by_tags");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("and_tags", and_tags);
            reqparams.Add("or_tags", or_tags);
            reqparams.Add("get_item_count", getItemCount.ToString().ToLower());
            if (fields != null) reqparams.Add("fields", Implode(fields));
            reqparams.Add("sort_order", sortOrder.ToString());
            reqparams.Add("sort_by", sortBy.ToString());
            if (pageNumber >= 0) reqparams.Add("page_number", pageNumber.ToString());
            if (pageSize >= 0) reqparams.Add("page_size", pageSize.ToString());
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static List<BCVideo> FindRelatedVideos(long videoId)
        {
            return FindRelatedVideos(videoId, -1, -1, null, false);
        }
 
        public static List<BCVideo> FindRelatedVideos(long videoId, int pageSize, int pageNumber)
        {
            return FindRelatedVideos(videoId, pageSize, pageNumber, null, false);
        }
 
        public static List<BCVideo> FindRelatedVideos(long videoId, int pageSize,
               int pageNumber, List<String> fields)
        {
            return FindRelatedVideos(videoId, pageSize, pageNumber, fields, false);
        }
 
        public static List<BCVideo> FindRelatedVideos( long videoId, int pageSize,
                int pageNumber, List<String> fields, Boolean getItemCount)
        {
            List<BCVideo> videos = new List<BCVideo>();
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
         //Build the REST parameter list
            reqparams.Add("command", "find_related_videos");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("video_id", videoId.ToString());
            reqparams.Add("get_item_count", getItemCount.ToString().ToLower());
            if (fields != null) reqparams.Add("fields", Implode(fields));
            if (pageNumber >= 0) reqparams.Add("page_number", pageNumber.ToString());
            if (pageSize >= 0) reqparams.Add("page_size", pageSize.ToString());
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static List<BCVideo> FindVideosByIds(List<long> videoIds)
        {
            return FindVideosByIds(videoIds, null);
        }
 
        public static List<BCVideo> FindVideosByIds(List<long>videoIds,
               List<String> fields)
        {            
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
            reqparams.Add("command", "find_videos_by_ids");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("video_ids", Implode(videoIds));
            if (fields != null) reqparams.Add("fields", Implode(fields));
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static List<BCVideo> FindVideosByReferenceIds(List<String> referenceIds)
        {
            return FindVideosByReferenceIds(referenceIds, null);
        }
 
        public static List<BCVideo> FindVideosByReferenceIds(List<String>
                referenceIds, List<String> fields)
        {
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
            reqparams.Add("command", "find_videos_by_reference_ids");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("reference_ids", Implode(referenceIds));
            if (fields != null) reqparams.Add("fields", Implode(fields));
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a list of videos
            return GetMultipleVideos(reader);
        }
 
        public static BCVideo FindVideoById(long videoId)
        {
            return FindVideoById(videoId, null);
        }
 
        public static BCVideo FindVideoById(long videoId, List<String> fields)
        {
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
         //Build the REST parameter list
            reqparams.Add("command", "find_video_by_id");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("video_id", videoId.ToString());
            if (fields != null) reqparams.Add("fields", Implode(fields));
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a single video
            return GetSingleVideo(reader);
        }
 
        public static BCVideo FindVideoByReferenceId(String referenceId)
        {
            return FindVideoByReferenceId(referenceId, null);
        }
 
        public static BCVideo FindVideoByReferenceId(String referenceId, List<String> fields)
        {
            BCAPIRequest req = new BCAPIRequest();
            Dictionary<String, String> reqparams = new Dictionary<string, string>();
 
            //Build the REST parameter list
         reqparams.Add("command", "find_video_by_reference_id");
            reqparams.Add("token", BCAPIConfig.ReadToken);
            reqparams.Add("reference_id", referenceId);
            if (fields != null) reqparams.Add("fields", Implode(fields));
 
            //Get the JSon reader returned from the APIRequest
            JsonReader reader = req.Execute(reqparams);
 
            //Return a single video
            return GetSingleVideo(reader);
        }
 
        private static List<BCVideo> GetMultipleVideos(JsonReader reader)
        {
            List<BCVideo> videos = new List<BCVideo>();
            //Get the first start object
            reader.Read();
            if (reader.TokenType == JsonToken.StartObject)
            {
                //Check if this is an array of videos
                reader.Read();
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    if (reader.Value.ToString() == "items")
                    {
                        reader.Read();
                        if (reader.TokenType == JsonToken.StartArray)
                        {
                            //Parse all video objects within the array
                            reader.Read();
                            while (reader.TokenType == JsonToken.StartObject)
                            {
                                BCVideo video = new BCVideo(reader);
                                videos.Add(video);
                            }
                        }
                    }
                    else if (reader.Value.ToString() == "error")
                    {
                        reader.Read();
                        Console.WriteLine(String.Format("Error: {0}", reader.Value));
                    }
                }
                else
                {
                    //Unexpected JSON format within string
                }
            }
            else
            {
                //Unexpected JSON format at beginning of string
            }
            return videos;
        }
 
 
        private static BCVideo GetSingleVideo(JsonReader reader)
        {
            BCVideo video = null;
            reader.Read();
            if (reader.TokenType == JsonToken.StartObject)
            {
                video = new BCVideo(reader);
            }
            else
            {
                Console.WriteLine(String.Format("Error: {0}", reader.Value));
                //Error handling
            }
            return video;
        }
 
        private static String Implode(List<String> values)
        {
            String result = "";
            foreach (String s in values)
            {
                result = result + s + ",";
            }
            return result;
        }
 
        private static String Implode(List<long> values)
        {
            String result = "";
            foreach (long l in values)
            {
                result = result + l.ToString() + ",";
            }
            return result;
        }
    }
 
    public enum BCSortByType {PUBLISH_DATE, CREATION_DATE, MODIFIED_DATE,
                              PLAYS_TOTAL, PLAYS_TRAILING_WEEK };
 
    public enum BCSortOrderType { ASC, DESC };
 
}

Using the classes in an application

That's it, we've created all the building blocks for a reusable Video read API library. Using the code is as simple as this console application:

using System;
using System.Collections.Generic;
using BrightcoveAPI;
using System.Text;
 
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            BCAPI.FindVideoByReferenceId("test", null);
            Console.ReadLine();
        }
    }
}

 

Post new comment

The content of this field is kept private and will not be shown publicly.
0

Comments