I've been looking around and all of the answers I've found are either not C#, use the V2.0 API or use a method that doesn't return a valid result for videos with embedding disabled.

Here's what I'm currently using, from a response I found a while back:

```
        public string GetYouTubeTitle(string url)
    {
        string id = GetArgs(url, "v", '?');
        WebClient client = new WebClient();
        return "YouTube Video: \"" + GetArgs(client.DownloadString("http://youtube.com/get_video_info?video_id=" + id), "title", '&') + "\""; 
    }

    public string GetArgs(string args, string key, char query)
    {
        int iqs = args.IndexOf(query);
        string querystring = null;

        if (iqs != -1)
        {
            querystring = (iqs < args.Length - 1) ? args.Substring(iqs + 1) : string.Empty;
            NameValueCollection nvcArgs = HttpUtility.ParseQueryString(querystring);
            return nvcArgs[key];
        }
        return string.Empty;
    }

```

It works perfectly the first time round, but the second video I tested returned the error: "&errorcode=150&reason=This+video+contains+content+from+Studio71\_1\_1.+It+is+restricted+from+playback+on+certain+sites"

My goal is just to get the title of a youtube video given the URL. But everything I'm seeing is either vague as hell or is only valid for the 2.0 API which doesn't even work anymore.

EDIT: And at some point I might want to add more to the response such as the length of the video. So I would prefer to have the API working than to just use something like get\_video\_info if possible.

EDIT:
For completeness and to help anyone who might be looking at this later on this is what I've got now that works like I want:

```
            string titleurl = "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" + GetArgs(url, "v", '?') + "&key=" + apikey;
            string timeurl = "https://www.googleapis.com/youtube/v3/videos?id=" + GetArgs(url, "v", '?') + "&part=contentDetails&key="  + apikey;

            HttpWebRequest titlerequest = (HttpWebRequest)WebRequest.Create(titleurl);
            HttpWebResponse titleresponse = (HttpWebResponse)titlerequest.GetResponse();
            Stream titlestream = titleresponse.GetResponseStream();
            StreamReader titlereader = new StreamReader(titlestream);
            string titlejson = titlereader.ReadToEnd();
            Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(titlejson);

            string title = (string)jObject["items"][0]["snippet"]["title"];

            HttpWebRequest timerequest = (HttpWebRequest)WebRequest.Create(timeurl);
            HttpWebResponse timeresponse = (HttpWebResponse)timerequest.GetResponse();
            Stream timestream = timeresponse.GetResponseStream();
            StreamReader timereader = new StreamReader(timestream);
            string timejson = timereader.ReadToEnd();
            Newtonsoft.Json.Linq.JObject jObjectTime = Newtonsoft.Json.Linq.JObject.Parse(timejson);

            string time = ParseTime((string)jObjectTime["items"][0]["contentDetails"]["duration"]);

            if (title.Length > 0 && time.Length > 0 && time != "0")
                return "YouTube Video: \"" + title + "\" (" + time + ")";
            else return error; //error is a preset generic error string

```

It's probably not the cleanest code around, but it's doing what I want. So I don't really mind.