Example #1
0
        /// <summary>
        /// Fetches the information about this video (including available streams and captions).
        /// Conains two synchronous HTTP fetches and several descrambling and signing algorithms.
        /// </summary>
        public async Task FetchInformation()
        {
            CSTube.Log("Fetching information of video " + videoID);

            // Page HTML
            watchHTML = await Helpers.ReadHTML(watchURL);

            if (string.IsNullOrEmpty(watchHTML))
            {
                return;
            }

            // PlayerConfig JSON
            playerConfig = Extract.getYTPlayerConfig(watchHTML);

            if (playerConfig.args == null || playerConfig.assets == null)
            {
                return;
            }

            // JavaScript Source
            string jsURL = Extract.getJSURL(playerConfig);

            jsSRC = await Helpers.ReadHTML(jsURL);

            // VideoInfo Raw Data
            //string videoInfoURL = Extract.getVideoInfoURL(videoID, watchURL, watchHTML);
            //videoInfoRAW = Helpers.ReadHTML(videoInfoURL);

            CSTube.Log("Finished downloading information! Continuing to parse!");

            // Parse Raw video info data
            //System.Collections.Specialized.NameValueCollection p = HttpUtility.ParseQueryString(videoInfoRAW);
            //videoInfo = ObscuredContainer.FromDictionary(p.AllKeys.ToDictionary(k => k, k => (object)p[k]));


            // Get all stream formats this video has (progressive and adaptive)
            List <string> streamMaps = new List <string>();

            streamMaps.Add("url_encoded_fmt_stream_map");
            if (playerConfig.args.ContainsKey("adaptive_fmts"))
            {
                streamMaps.Add("adaptive_fmts");
            }
            foreach (string streamFormat in streamMaps)
            {
                // Descramble stream data in player args
                ObscuredContainer streamBundle = Mixins.ApplyDescrambler(playerConfig.args, streamFormat);

                // If required, apply signature to the stream URLs
                Mixins.ApplySignature(streamBundle, jsSRC);

                // Write stream data into Stream objects
                foreach (object streamData in streamBundle.Values)
                {
                    formatStreams.Add(new Stream((ObscuredContainer)streamData));
                }
            }


            // Try to read out captionTracks if existant
            ObscuredContainer captionTrackBundle =
                Helpers.TryGetAttribute <ObscuredContainer>(playerConfig.args,
                                                            "player_response/captions/playerCaptionsTracklistRenderer/captionTracks");

            if (captionTrackBundle != null)
            {             // Write caption tracks into Caption objects
                foreach (object captionTrack in captionTrackBundle.Values)
                {
                    captionTracks.Add(new Caption((ObscuredContainer)captionTrack));
                }
            }

            videoDataAvailable = true;

            // Log success!
            CSTube.Log(string.Format(
                           "Finished parsing video data! Found {0} video streams and {1} caption tracks for video '{2}'!",
                           formatStreams.Count, captionTracks.Count, title
                           ));
            CSTube.Log(string.Format("Video Streams: \n \t " +
                                     string.Join(" \n \t ", formatStreams.Select(s => s.ToString()))
                                     ));
            if (captionTracks.Count > 0)
            {
                CSTube.Log(string.Format("Caption Tracks: \n \t " +
                                         string.Join(" \n \t ", captionTracks.Select(s => s.ToString()))
                                         ));
            }
        }
Example #2
0
 /// <summary>
 /// Creates a new Youtube video inspector.
 /// If defeFetch is false, automatically fetches video information (many HTTP fetches) synchronously.
 /// </summary>
 public Video(string url)
 {
     videoID  = Extract.getVideoID(url);
     watchURL = Extract.getWatchURL(videoID);
 }