class TYTD.SDVideoDownload : IVideoDownload { private info; private tytd; private progress; private video_stream_url; private done=false; public SDVideoDownload(id) { this.info = { Title = "", Channel = "", VideoId = TYTD.GetVideoId(id), ChannelId = "" }; } public setTYTD(tytd) { this.tytd = tytd; var id = this.info.VideoId; var path = /"Streams"/id.Substring(0,4)/id.Substring(4)/"ytmux.mp4"; if(this.tytd.Storage.FileExists(path)) { this.done = true; return tytd; } var req = this.tytd.ManifestRequest(id).playerResponse; this.info.Title = req.videoDetails.title; this.info.Channel = req.videoDetails.author; this.info.ChannelId = req.videoDetails.channelId; this.tytd.PutVideoInfo(req.videoDetails); this.video_stream_url = req.streamingData.formats[0].url; return tytd; } public setProgress(p) { this.progress = p; this.progress(0.0); } public getVideo() { return this.info; } public Start() { for(var i = 0; i < 5; i++) { var req = { FollowRedirects = true, RequestHeaders = [ { Key = "User-Agent", Value = "com.google.android.youtube/19.28.35 (Linux; U; Android 15; GB) gzip" } ] }; var resp = Net.Http.MakeRequest(this.video_stream_url,req); if(resp.StatusCode >= 200 && resp.StatusCode <= 299) { var id = this.info.VideoId; var path = /"Streams"/id.Substring(0,4)/id.Substring(4)/"ytmux.mp4"; this.tytd.Storage.CreateDirectory(path.GetParent()); var strm = this.tytd.Storage.OpenFile(path+".part","wb"); var src = resp.ReadAsStream(); Helpers.CopyToProgress(src,strm,this.progress,100.0); strm.Close(); src.Close(); this.tytd.Storage.MoveFile(path+".part",path); break; } else { var req = this.tytd.ManifestRequest(this.info.VideoId).playerResponse; this.video_stream_url = req.streamingData.formats[0].url; } } } }