public async Task<IHttpActionResult> DownloadCourseModuleClip(string clipname, ClipToSave clipToSave) { string clipUrl = string.Empty; // 1- get the video clip url to download. try { clipUrl = GetClipUrl(clipToSave); // 2- make sure the folders structure exist. var videoSaveDirectory = SetUpVideoFolderStructure(clipToSave.CourseTitle, (clipToSave.ModuleIndex + 1).ToString("D2") + " - " + clipToSave.ModuleTitle, (clipToSave.ClipIndex + 1).ToString("D2") + " - " + clipToSave.Title); // 3- download the video and report progress back. int receivedBytes = 0; long totalBytes = 0; var videoFileName = ((clipToSave.ClipIndex + 1).ToString("D2") + " - " + clipToSave.Title + ".mp4").ToValidFileName(); var videoSaveLocation = videoSaveDirectory.FullName + "\\raw-" + videoFileName; using (var client = new WebClient()) using (var regStream = await client.OpenReadTaskAsync(clipUrl)) using (var stream = new ThrottledStream(regStream, 115200)) { byte[] buffer = new byte[1024]; totalBytes = Int32.Parse(client.ResponseHeaders[HttpResponseHeader.ContentLength]); stream.MaximumBytesPerSecond = GetClipMaxDownloadSpeed(clipToSave.DurationSeconds, totalBytes); using (var fileStream = File.OpenWrite(videoSaveLocation)) { for (;;) { int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); if (bytesRead == 0) { await Task.Yield(); break; } receivedBytes += bytesRead; var progress = new ProgressArgs() { Id = clipToSave.Name, BytesReceived = receivedBytes, FileName = videoFileName, TotalBytes = totalBytes, IsDownloading = true, Extra = new { clipToSave.ModuleIndex, clipToSave.ClipIndex } }; fileStream.Write(buffer, 0, bytesRead); var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>(); hubContext.Clients.All.updateProgress(progress); } } } // 4- save the video file. var inputFile = new MediaFile { Filename = videoSaveDirectory.FullName + "\\raw-" + videoFileName }; var outputFile = new MediaFile { Filename = videoSaveDirectory.FullName + "\\" + videoFileName }; File.Move(inputFile.Filename, outputFile.Filename); // 5- Create srt files if (Constants.SUBTITLES) { var srtFilename = outputFile.Filename.Substring(0, outputFile.Filename.Length - 4) + ".srt"; var srtString = clipToSave.TranscriptClip.GetSrtString(clipToSave.DurationSeconds); File.WriteAllText(srtFilename, srtString); } return Ok(new ProgressArgs() { Id = clipToSave.Name, BytesReceived = receivedBytes, FileName = videoFileName, TotalBytes = totalBytes, IsDownloading = false, Extra = new { clipToSave.ModuleIndex, clipToSave.ClipIndex } }); } catch (Exception exception) { return HandleException(exception); } }
private string GetClipUrl(ClipToSave clip) { var http = (HttpWebRequest)WebRequest.Create(new Uri(Constants.COURSE_CLIP_DATA_URL)); http.Accept = "application/json"; http.ContentType = "application/json"; http.Method = "POST"; http.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0"; var playerParameters = HttpUtility.ParseQueryString(clip.PlayerParameters); var playerParametersObj = new { a = playerParameters["author"], m = playerParameters["name"], course = playerParameters["course"], cn = playerParameters["clip"], mt = "mp4", q = (clip.SupportsWideScreenVideoFormats ? "1280x720" : "1024x768"), cap = false, lc = "en" }; var encoding = new ASCIIEncoding(); Byte[] dataBytes = encoding.GetBytes(JsonConvert.SerializeObject(playerParametersObj)); using (Stream sendStream = http.GetRequestStream()) sendStream.Write(dataBytes, 0, dataBytes.Length); // if the clip is not free, then the user must sign in first and set authentication cookie. if (!clip.UserMayViewClip) SetupAuthenticationCookie(http); try { using (var response = http.GetResponse()) using (var receiveStream = response.GetResponseStream()) using (var sr = new StreamReader(receiveStream)) { var clipurl = sr.ReadToEnd(); return clipurl; } } catch { logger.Error("Couldn't retrieve clip URL. Request parameters={0}", JsonConvert.SerializeObject(playerParametersObj)); throw new Exception("Couldn't retrieve clip URL. Please check log file."); } }