Exemple #1
0
        public async Task <M3U8DownloadResult> DownloadM3U8FilesAsParallel(M3U8File mfile, string savedir, CancellationToken token, bool skipexistfile = true)
        {
            var result = new M3U8DownloadResult();

            try
            {
                Directory.CreateDirectory(savedir);
                DownloadM3U8Head(mfile.Head, savedir);
                if (token.IsCancellationRequested)
                {
                    result.IsCancelled = true;
                    return(result);
                }
                var action = new Action <M3U8Segment, bool>((node, succ) =>
                {
                    if (succ)
                    {
                        result.DownloadedNodes.Add(node);
                    }
                    var e = new M3U8VideoDownloadProgressChangedArgs(mfile, node)
                    {
                        IsNodeDownloadSuccess = succ,
                        Count = result.DownloadedNodes.Count
                    };
                    OnReport(e);
                });
                await DownloadM3U8SegmentsAsParallel(mfile.Segments, savedir, token, skipexistfile, action);
            }
            catch (Exception ex)
            {
                result.Exception = ex;
            }
            return(result);
        }
Exemple #2
0
        /// <summary>
        /// 解密(如果需要)并合并M3U8片段为一个文件
        /// </summary>
        /// <param name="target"></param>
        /// <param name="srcdir"></param>
        /// <param name="dstfile"></param>
        /// <param name="ignoreerror"></param>
        public static async Task <OperateResult> CombineM3U8Segments(M3U8File target, string srcdir, string dstfile, Action <M3U8SegmentsCombineProgressChangedEventArgs> progressChangedAction = null, bool ignoreerror = true)
        {
            var result = new OperateResult();

            try
            {
                using (var fs = new FileStream(dstfile, FileMode.Create, FileAccess.ReadWrite))
                {
                    var totallength = target.Segments.Length;
                    for (var index = 0; index < totallength; index++)
                    {
                        var node    = target.Segments[index];
                        var srcfile = Path.Combine(srcdir, node.SegmentName);
                        var arg     = new M3U8SegmentsCombineProgressChangedEventArgs
                        {
                            M3U8File     = target,
                            IsInProgress = true,
                            CurrIndex    = index,
                            IsComplete   = false
                        };
                        if (File.Exists(srcfile))
                        {
                            if (target.Head.IsEncrypt || node.IsEncrypt)
                            {
                                var buff = File.ReadAllBytes(srcfile);
                                var data = AesDecrypt(buff, target.Head.Key, target.Head.IV);
                                await fs.WriteAsync(data, 0, data.Length);
                            }
                            else
                            {
                                var srcfs = new FileStream(srcfile, FileMode.Open);
                                await srcfs.CopyToAsync(fs);

                                fs.Flush();
                            }
                            arg.CurrNodeCombined = true;
                        }
                        else
                        {
                            if (ignoreerror)
                            {
                                arg.CurrNodeCombined = false;
                            }
                            else
                            {
                                throw new FileNotFoundException();
                            }
                        }
                        progressChangedAction?.Invoke(arg);
                    }
                }
                result.IsComplete = true;
            }
            catch (Exception ex)
            {
                result.Exception = ex;
                System.Diagnostics.Trace.TraceWarning($"CombineM3U8Segments Ex:{ex.Message}");
            }
            return(result);
        }
Exemple #3
0
        public static string GetM3U8Content(M3U8File m3u8, bool keepurl)
        {
            StringBuilder sb   = new StringBuilder();
            var           maxd = m3u8.Segments.Max(p => p.Seconds);

            maxd = Math.Truncate(maxd) + 1;
            sb.Append("#EXTM3U\n");
            sb.Append($"#EXT-X-VERSION:{m3u8.Head.VERSION}\n");
            sb.Append($"#EXT-X-TARGETDURATION:{m3u8.Head.TARGETDURATION}\n");
            sb.Append($"#EXT-X-MEDIA-SEQUENCE:{m3u8.Head.MEDIA_SEQUENCE}\n");
            if (keepurl)
            {
                if (m3u8.Head.HasMap)
                {
                    sb.Append($"#EXT-X-MAP:URI=\"{m3u8.Head.MapUrl}\",\n");
                }
                if (m3u8.Head.IsEncrypt)
                {
                    sb.Append($"#EXT-X-KEY:METHOD={m3u8.Head.EncryptMethod},KEYURI=\"{m3u8.Head.KeyUrl}\"\n");
                }
                foreach (var node in m3u8.Segments)
                {
                    sb.Append($"#EXTINF:{node.Seconds},\n");
                    sb.Append($"{node.Target}\n");
                }
            }
            else
            {
                if (m3u8.Head.HasMap)
                {
                    var mapurl = new Uri(m3u8.Head.MapUrl);
                    sb.Append($"#EXT-X-MAP:URI=\"{mapurl.LocalPath.Substring(mapurl.LocalPath.LastIndexOf('/') + 1)}\",\n");
                }
                if (m3u8.Head.IsEncrypt)
                {
                    var keyurl = new Uri(m3u8.Head.KeyUrl);
                    sb.Append($"#EXT-X-KEY:METHOD={m3u8.Head.EncryptMethod},KEYURI=\"{keyurl.LocalPath.Substring(keyurl.LocalPath.LastIndexOf('/') + 1)}\"\n");
                }
                foreach (var node in m3u8.Segments)
                {
                    sb.Append($"#EXTINF:{node.Seconds},\n");
                    sb.Append($"{node.SegmentName}\n");
                }
            }
            sb.Append("#EXT-X-ENDLIST\n");
            return(sb.ToString());
        }
Exemple #4
0
        public static M3U8File AnalyzeM3U8Content(Uri url, string content)
        {
            if (!content.StartsWith("#EXTM3U"))
            {
                return(null);
            }
            var path = url.LocalPath;

            path = path.Substring(0, path.LastIndexOf('/') + 1);
            var fixurl = url.Scheme + "://" + url.Authority + path;
            var fixuri = new Uri(fixurl);
            var head   = AnalyzeM3U8Head(fixuri, content);
            var nodes  = AnalyzeSegments(fixuri, content);
            var m3u8   = new M3U8File(url, head, nodes);

            return(m3u8);
        }
Exemple #5
0
        /// <summary>
        /// 异步下载M3U8视频
        /// </summary>
        /// <param name="target"></param>
        /// <param name="savedir"></param>
        public async Task <M3U8DownloadResult> DownloadM3U8VideoFilesAsync(M3U8File target, string savedir, CancellationToken token, bool skipexistsegment = false)
        {
            var result = new M3U8DownloadResult();

            try
            {
                Directory.CreateDirectory(savedir);
                await Task.Factory.StartNew(() => DownloadM3U8Head(target.Head, savedir), token);

                var action = new Action <M3U8Segment, bool>((node, succ) =>
                {
                    if (succ)
                    {
                        result.DownloadedNodes.Add(node);
                    }
                    var arg = new M3U8VideoDownloadProgressChangedArgs(target, node)
                    {
                        IsNodeDownloadSuccess = succ,
                        Count = result.DownloadedNodes.Count
                    };
                    OnReport(arg);
                    token.ThrowIfCancellationRequested();
                });
                result.IsCancelled = await DownloadM3U8VideoSegments(target.Segments, savedir, skipexistsegment, action);

                if (!result.IsCancelled)
                {
                    result.IsComplete = true;
                }
            }
            catch (Exception ex)
            {
                result.Exception = ex;
            }
            return(result);
        }
Exemple #6
0
        public static void SaveToFile(M3U8File m3u8, string filename, bool keepurl = true)
        {
            var content = GetM3U8Content(m3u8, keepurl);

            File.WriteAllText(filename, content);
        }
Exemple #7
0
 public M3U8SegmentDownloadedEventArgs(M3U8Segment node, M3U8File file)
 {
     Segment  = node;
     M3U8File = file;
 }
Exemple #8
0
 public M3U8VideoDownloadProgressChangedArgs(M3U8File file, M3U8Segment node)
 {
     File       = file;
     Node       = node;
     TotalCount = file.Segments.Length;
 }