public void Stop() { ffprobe = null; done = true; if (thread != null && thread.IsAlive) { thread.Interrupt(); } }
protected void ResizeCanvas() { if (ffprobe == null) { return; } Render.DoAction(() => { var vs = new Size(ffprobe.Width, ffprobe.Height); try { var aw = blackRect.ActualWidth; var ah = blackRect.ActualHeight; var dxv = (double)vs.Width / (double)vs.Height; var dxc = aw / ah; double w, h; if (dxv < dxc) { h = blackRect.ActualHeight; w = dxv * blackRect.ActualHeight; } else { w = blackRect.ActualWidth; h = blackRect.ActualWidth / dxv; } var dw = Convert.ToDouble((aw - w) / 2); var dh = Convert.ToDouble((ah - h) / 2); margin = new Thickness(dw, dh, dw, dh); mediaElement1.Margin = new Thickness(dw, dh, dw, dh); mediaElement2.Margin = new Thickness(dw, dh, dw, dh); } catch { ffprobe = null; } }); }
private static String GetCommandLine( String videoDevice, String audioDevice, String outPath, Quality quality, int segment_start_number) { var yadif = "yadif,"; var conv = String.Format("0:0", 0); var con_filter = String.Empty; var res = String.Format("-f dshow -rtbufsize 2004000k -i video=\"{0}\"", videoDevice); res += String.Format(" -f dshow -i audio=\"{0}\"", audioDevice); res += String.Format(" -i \".\\logo\\logo{0}.png\"", quality.ToString()); res += " -filter_complex \"" + con_filter; var source_par = 1.0; var dev_str = String.Format("-f dshow -i video=\"{0}\"", videoDevice); var ffprobe = new Ffprobe(dev_str); var source_height = ffprobe.Height; var source_width = ffprobe.Width; var target_full = GetSizeByQuality(quality); var source_dar = (double)source_width / (double)source_height * source_par; var target_dar = (double)target_full.Width / (double)target_full.Height; var pad_x = 0; var pad_y = 0; double target_inner_height = 0; double target_inner_width = 0; var scale = 0.0; if (source_dar < target_dar) { target_inner_height = target_full.Height; scale = (double)target_inner_height / (double)source_height; target_inner_width = (double)source_width * scale * source_par; if (target_full.Width / 2 == (double)target_full.Width / 2.0) { target_inner_width = Math.Round(target_inner_width / 2.0) * 2.0; } else { target_inner_width = Math.Round((target_inner_width - 1) / 2.0) * 2.0 + 1; } if (target_inner_width < target_full.Width) { pad_x = Convert.ToInt32((target_full.Width - target_inner_width) / 2); pad_y = 0; } else { target_inner_width = target_full.Width; pad_x = 0; pad_y = 0; } } else { target_inner_width = target_full.Width; scale = (double)target_inner_width / (double)source_width; target_inner_height = Convert.ToInt32((double)source_height * scale / source_par); if (target_full.Height / 2 == (double)target_full.Height / 2.0) { target_inner_height = Math.Round(target_inner_height / 2.0) * 2.0; } else { target_inner_height = Math.Round((target_inner_height - 1) / 2.0) * 2.0 + 1; } if (target_inner_height < target_full.Height) { //Необходимо добавить поля сверху и снизу //Расчитать ширину каждого поля: pad_x = 0; pad_y = Convert.ToInt32((target_full.Height - target_inner_height) / 2); } else { //Поля не нужны target_inner_height = target_full.Height; pad_x = 0; pad_y = 0; } } var scale_width = Convert.ToInt32(target_inner_width == source_width ? 0 : target_inner_width); var scale_height = Convert.ToInt32(target_inner_height == source_height ? 0 : target_inner_height); var pad_width = (target_full.Width == target_inner_width ? 0 : target_full.Width); var pad_height = (target_full.Height == target_inner_height ? 0 : target_full.Height); res += String.Format("[{0}]{1}setsar=1/1", conv, yadif); if (scale_width != 0 || scale_height != 0) { res += ",scale=" + scale_width + ":" + scale_height; } if (pad_x != 0 || pad_y != 0) { res += ",pad=" + pad_width + ":" + pad_height + ":" + pad_x + ":" + pad_y + ":black"; } res += "[conv]; "; var wmo = GetWatermarkOffset(quality); res += String.Format("[conv][{2}:v]overlay={0}:main_h-overlay_h-{1} [mvid]", wmo.X, wmo.Y, 2); res += "\""; res += GetVideoParametersString(quality); res += " -x264opts keyint=25:" + "b-pyramid=normal:no-mixed-refs=1:no-8x8dct=1:no-fast-pskip=" + " -fpre .\\ffmpeg\\presets\\libx264-slow.ffpreset" + " -threads 0 -profile:v baseline"; res += " -f mp4"; res += " -metadata title=\"InStat Football video\""; res += " -map_chapters -1"; res += " -map \"[mvid\"]"; res += " -map 1:0"; res += " -sn"; res += String.Format(" -f segment -segment_list \"{0}\\out.m3u8\" -segment_time 5 -segment_start_number {1} -segment_format mp4 \"{0}\\out%06d.mp4", outPath, segment_start_number); return(res); }
private void DoStart() { try { done = false; scenes.Clear(); openScene = false; DurationTotal = 0; DurationUpload = 0; ffprobe = null; var ci = new System.Globalization.CultureInfo("en-us"); Thread.CurrentThread.CurrentCulture = ci; switch (MediaType) { case MediaTypeEnum.NETWORK_STREAM: #region NETWORK_STREAM var wc = new WebClient(); while (!done) { var baseUrl = Uri + "/"; try { wc.DownloadFile(baseUrl + "out.m3u8", CacheDirectory + "_out.m3u8"); } catch (Exception ex) { if (DownloadPlaylistResult != null) { DownloadPlaylistResult(this, new DownloadPlaylistResultEventAgrs { ErrorCode = ex }); } Thread.Sleep(1000); continue; } if (DownloadPlaylistResult != null) { DownloadPlaylistResult(this, new DownloadPlaylistResultEventAgrs { ErrorCode = null }); } ParseOut(CacheDirectory + "_out.m3u8"); if (done) { return; } var upList = new List <Scene>(); lock (scenes) { DurationTotal = scenes.Sum(o => o.Len); upList = scenes.Where(o => !o.Uploaded).ToList <Scene>(); } if (done) { return; } if (upList.Count > 0) { foreach (var sc in upList) { var t0 = DateTime.Now.ToFileTime(); if (done) { return; } try { wc.DownloadFile(baseUrl + sc.Name, CacheDirectory + sc.Name); } catch (Exception ex) { if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = ex, Scene = sc }); } break; } if (done) { return; } if (File.Exists(CacheDirectory + sc.Name)) { var t = (float)(DateTime.Now.ToFileTime() - t0) / (float)10000; var sz = (new FileInfo(CacheDirectory + sc.Name)).Length; sc.Uploaded = true; sc.Size = sz; sc.Speed = sz / (t / 1000.0f); // *(8.0f / 1024.0f / 1024.0f); lock (scenes) lock (upscs) { upscs.Clear(); upscs.AddRange(scenes.Where(o => o.Uploaded)); DurationUpload = upscs.Sum(o => o.Len); } if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = null, Scene = sc }); } if (!openScene) { long start_position = Position; if (needPosition > 0L) { start_position = Math.Max(needPosition, CurrentConnectorSecond); if (DurationUpload >= 500 + start_position && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(start_position, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + start_position && buffering) { Open(currentScene + 1, 0, false); } } if (ffprobe == null) { ffprobe = new Ffprobe(CacheDirectory + sc.Name); if (ffprobe != null) { ResizeCanvas(); if (FfprobeDetected != null) { FfprobeDetected(this, EventArgs.Empty); } } } } } else { break; } if (done) { return; } } } else { if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } } Thread.Sleep(1000); } break; #endregion case MediaTypeEnum.LOCAL_STREAM: #region LOCAL_STREAM while (!done) { var baseUrl = new FileInfo(Uri).Directory.FullName; ParseOut(Uri); if (done) { return; } var upList = new List <Scene>(); Scene last = null; lock (scenes) { DurationTotal = scenes.Sum(o => o.Len); upList = scenes.Where(o => !o.Uploaded).ToList <Scene>(); if (scenes.Count > 0) { last = scenes[scenes.Count - 1]; } } if (ffprobe == null && last != null) { ffprobe = new Ffprobe(baseUrl + "\\" + last.Name); if (ffprobe != null && ffprobe.Width > 0) { ResizeCanvas(); if (FfprobeDetected != null) { FfprobeDetected(this, EventArgs.Empty); } } } if (done) { return; } if (upList.Count > 0) { foreach (var sc in upList) { var t0 = DateTime.Now.ToFileTime(); if (done) { return; } try { File.Copy(baseUrl + "\\" + sc.Name, CacheDirectory + sc.Name, true); } catch (Exception ex) { Render.DoAction(() => { labelError.Visibility = Visibility.Visible; labelError.Content = ex.Message; }); if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = ex, Scene = sc }); } break; } Render.DoAction(() => { labelError.Visibility = Visibility.Hidden; labelError.Content = ""; }); if (done) { return; } if (File.Exists(CacheDirectory + sc.Name)) { var t = (float)(DateTime.Now.ToFileTime() - t0) / (float)10000; var sz = (new FileInfo(CacheDirectory + sc.Name)).Length; sc.Uploaded = true; sc.Size = sz; sc.Speed = sz / (t / 1000.0f); // *(8.0f / 1024.0f / 1024.0f); lock (scenes) lock (upscs) { upscs.Clear(); upscs.AddRange(scenes.Where(o => o.Uploaded)); DurationUpload = upscs.Sum(o => o.Len); } if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = null, Scene = sc }); } } else { break; } if (done) { return; } if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } } } else { if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } } Thread.Sleep(1000); } break; #endregion case MediaTypeEnum.FLAT_FILE: #region FLAT_FILE ffprobe = new Ffprobe(Uri); if (ffprobe != null) { var sc = new Scene { Name = Uri, Index = 0, Len = Convert.ToInt32(ffprobe.Duration), Uploaded = true }; lock (scenes) scenes.Add(sc); lock (upscs) { upscs.Clear(); upscs.Add(sc); DurationUpload = upscs.Sum(o => o.Len); } lock (scenes) DurationTotal = scenes.Sum(o => o.Len); ResizeCanvas(); if (FfprobeDetected != null) { FfprobeDetected(this, EventArgs.Empty); } Open(0, 0, false); } break; #endregion } } catch (ThreadInterruptedException e) { } }
private void StartScene() { if (openScene) { return; } if (closed) { openScene = true; closed = false; try { Scene sc = null; lock (upscs) sc = upscs[_num]; CurrentSceneFileName = sc.Name; switch (MediaType) { case MediaTypeEnum.LOCAL_STREAM: CurrentSceneFileName = new FileInfo(Uri).Directory.FullName + @"\" + sc.Name; break; case MediaTypeEnum.NETWORK_STREAM: CurrentSceneFileName = CacheDirectory + sc.Name; break; } //var curr_pl = MediaElement.Name; curr_player = !curr_player; try { //lock (MediaElement) if (MediaElement.Source == null || !MediaElement.Source.AbsoluteUri.Contains(sc.Name)) { MediaElement.Source = new Uri(CurrentSceneFileName); } } catch (Exception exc) { lock (MediaElement) MediaElement.Source = new Uri(CurrentSceneFileName); } MediaElement.Visibility = System.Windows.Visibility.Visible; MediaElementShadow.Visibility = System.Windows.Visibility.Hidden; MediaElement.Play(); //curr_pl = MediaElement.Name; buffering = false; if (MediaBuffering != null) { MediaBuffering(this, EventArgs.Empty); } needPosition = 0L; if (sc.Index > 1 && MediaType != MediaTypeEnum.FLAT_FILE && scenes.Exists(o => o.Index == sc.Index + 1)) { var next = scenes.First(o => o.Index == sc.Index + 1); var fn = string.Empty; switch (MediaType) { case MediaTypeEnum.LOCAL_STREAM: fn = new FileInfo(Uri).Directory.FullName + @"\" + next.Name; break; case MediaTypeEnum.NETWORK_STREAM: fn = CacheDirectory + next.Name; break; } MediaElementShadow.Source = new System.Uri(fn); MediaElementShadow.Position = TimeSpan.FromMilliseconds(5); MediaElementShadow.Pause(); } if (_pos > 0) { MediaElement.Position = TimeSpan.FromMilliseconds(_pos); } if (_set_on_pause) { if (Mode == PlayerMode.Pause) { MediaElement.Pause(); } } if (ffprobe == null || MediaType == MediaTypeEnum.FLAT_FILE) { ffprobe = new Ffprobe(CurrentSceneFileName); } if (ffprobe != null) { VideoSize = new Size(ffprobe.Width, ffprobe.Height); ResizeCanvas(); } } catch (Exception ex) { Debug.WriteLine("Exception " + ex.Message); } finally { currentScene = _num; openScene = false; } } }
private void DoStart() { try { done = false; scenes.Clear(); openScene = false; DurationTotal = 0; DurationUpload = 0; ffprobe = null; var ci = new System.Globalization.CultureInfo("en-us"); Thread.CurrentThread.CurrentCulture = ci; switch (MediaType) { case MediaTypeEnum.NETWORK_STREAM: var wc = new WebClient(); while (!done) { var baseUrl = Uri + "/"; try { wc.DownloadFile(baseUrl + "out.m3u8", CacheDirectory + "_out.m3u8"); } catch (Exception ex) { if (DownloadPlaylistResult != null) { DownloadPlaylistResult(this, new DownloadPlaylistResultEventAgrs { ErrorCode = ex }); } Thread.Sleep(1000); continue; } if (DownloadPlaylistResult != null) { DownloadPlaylistResult(this, new DownloadPlaylistResultEventAgrs { ErrorCode = null }); } ParseOut(CacheDirectory + "_out.m3u8"); if (done) { return; } Scene last = null; var upList = new List <Scene>(); lock (scenes) { DurationTotal = scenes.Sum(o => o.Len); upList = scenes.Where(o => !o.Uploaded).ToList <Scene>(); if (scenes.Count > 0) { last = scenes[0]; } } if (done) { return; } if (upList.Count > 0) { var tasks = CreateAndExecTasks(upList, baseUrl, 3); var exeption_flag = false; foreach (var sc in tasks) { //Если была ошибка или на предыдущем моменте облом if (sc.DownloadException != null || exeption_flag) { exeption_flag = true; sc.DownloadException = null; sc.Uploaded = false; continue; } lock (scenes) lock (upscs) { upscs.Clear(); upscs.AddRange(scenes.Where(o => o.Uploaded)); DurationUpload = upscs.Sum(o => o.Len); } if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = null, Scene = sc }); } if (ffprobe == null && last != null) { ffprobe = new Ffprobe(CacheDirectory + last.Name); if (ffprobe.Width == 0) { ffprobe = null; } if (ffprobe != null) { VideoSize = new Size(ffprobe.Width, ffprobe.Height); ResizeCanvas(); if (FfprobeDetected != null) { FfprobeDetected(this, EventArgs.Empty); } } } if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } var shadow_fn = String.Empty; float sc_curr_t = 0; UISync.Execute(() => { try { sc_curr_t = GetCurrentSceneSecond(); shadow_fn = MediaElementShadow != null && !String.IsNullOrEmpty(MediaElementShadow.FileName) ? MediaElementShadow.FileName : String.Empty; } catch { } }); if (currentScene >= 0 && currentScene + 1 == sc.Index && sc_curr_t < 8000 && !shadow_fn.Contains(sc.Name)) { Scene sc_curr = null; lock (scenes) if (scenes.Any(o => o.Index == currentScene)) { sc_curr = scenes.First(o => o.Index == currentScene); } if (sc_curr != null) { UISync.Execute(() => { PreloadScene(sc_curr); }); } } } } } else { if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } } Thread.Sleep(1000); } break; case MediaTypeEnum.LOCAL_STREAM: while (!done) { var baseUrl = new FileInfo(Uri).Directory.FullName; ParseOut(Uri); if (done) { return; } var upList = new List <Scene>(); Scene last = null; lock (scenes) { DurationTotal = scenes.Sum(o => o.Len); upList = scenes.Where(o => !o.Uploaded).ToList <Scene>(); if (scenes.Count > 0) { last = scenes[0]; } } if (done) { return; } if (upList.Count > 0) { foreach (var sc in upList) { var t0 = DateTime.Now.ToFileTime(); if (done) { return; } try { File.Copy(baseUrl + "\\" + sc.Name, CacheDirectory + sc.Name, true); } catch (Exception ex) { if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = ex, Scene = sc }); } break; } if (done) { return; } if (File.Exists(CacheDirectory + sc.Name)) { var t = (float)(DateTime.Now.ToFileTime() - t0) / (float)10000; var sz = (new FileInfo(CacheDirectory + sc.Name)).Length; sc.Uploaded = true; sc.Size = sz; lock (scenes) lock (upscs) { upscs.Clear(); upscs.AddRange(scenes.Where(o => o.Uploaded)); DurationUpload = upscs.Sum(o => o.Len); } if (DownloadSceneResult != null) { DownloadSceneResult(this, new DownloadSceneResultEventAgrs { ErrorCode = null, Scene = sc }); } } else { break; } if (done) { return; } if (ffprobe == null && last != null) { ffprobe = new Ffprobe(CacheDirectory + last.Name); if (ffprobe.Width == 0) { ffprobe = null; } if (ffprobe != null) { VideoSize = new Size(ffprobe.Width, ffprobe.Height); ResizeCanvas(); if (FfprobeDetected != null) { FfprobeDetected(this, EventArgs.Empty); } } } if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } } } else { if (!openScene) { if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } } Thread.Sleep(1000); } break; case MediaTypeEnum.FLAT_FILE: ffprobe = new Ffprobe(Uri); if (ffprobe != null) { var sc = new Scene(); sc.Name = Uri; sc.Index = 0; sc.Len = Convert.ToInt32(ffprobe.Duration); sc.Uploaded = true; lock (scenes) scenes.Add(sc); lock (upscs) { upscs.Clear(); upscs.Add(sc); DurationUpload = upscs.Sum(o => o.Len); } lock (scenes) DurationTotal = scenes.Sum(o => o.Len); VideoSize = new Size(ffprobe.Width, ffprobe.Height); ResizeCanvas(); if (FfprobeDetected != null) { FfprobeDetected(this, EventArgs.Empty); } Open(0, 0, false); if (needPosition > 0L) { if (DurationUpload >= 500 + needPosition && buffering) { var n = 0; long ofss = 0; if (GetSceneAndOffset(needPosition, out n, out ofss)) { Open(n, ofss, false); } } } else { if (DurationUpload >= 500 + Position && buffering) { Open(currentScene + 1, 0, false); } } } break; } } catch (ThreadInterruptedException e) { } }
private void StartScene() { if (openScene) { return; } if (closed) { openScene = true; closed = false; try { Scene sc = null; lock (upscs) sc = upscs[_num]; CurrentSceneFileName = sc.Name; switch (MediaType) { case MediaTypeEnum.LOCAL_STREAM: CurrentSceneFileName = new FileInfo(Uri).Directory.FullName + @"\" + sc.Name; break; case MediaTypeEnum.NETWORK_STREAM: CurrentSceneFileName = CacheDirectory + sc.Name; break; } curr_player = !curr_player; if (String.IsNullOrEmpty(MediaElement.FileName) || !MediaElement.FileName.Contains(sc.Name)) { MediaElement.Open(CurrentSceneFileName); MediaElement.Play(); } else { MediaElement.CurrentPosition = 0; MediaElement.Play(); } MediaElement.Volume = volume; MediaElement.BringToFront(); MediaElement.AudioStream = 0; buffering = false; if (MediaBuffering != null) { MediaBuffering(this, EventArgs.Empty); } needPosition = 0L; PreloadScene(sc); if (_pos > 0) { MediaElement.CurrentPosition = (double)_pos / 1000.0; } if (_set_on_pause) { if (Mode == PlayerMode.Pause) { MediaElement.Pause(); } } if (ffprobe == null || MediaType == MediaTypeEnum.FLAT_FILE) { ffprobe = new Ffprobe(CurrentSceneFileName); } } catch (Exception ex) { Log.WriteException(ex); } finally { currentScene = _num; openScene = false; } } }