예제 #1
0
        private List <TsFileInfo> GetPieces(string hls_pl)
        {
            List <TsFileInfo> pieces = new List <TsFileInfo>();

            TsFileInfo currInfo = new TsFileInfo()
            {
                name = null, size = 0
            };

            foreach (string line in hls_pl.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                if (IsValidLine(line))
                {
                    TsFileInfo tsInfo = GetInfoFromLine(line);
                    if (tsInfo.name != currInfo.name)
                    {
                        // Starting a new TS file

                        // If we are not at the first entry, list the piece
                        if (currInfo.name != null)
                        {
                            pieces.Add(currInfo);
                        }

                        // Begin the new piece from our current line
                        currInfo = tsInfo;
                    }
                    else
                    {
                        // Continuing an existing piece, only update end offset
                        currInfo.end_offset = tsInfo.end_offset;
                        currInfo.size      += tsInfo.size;
                    }
                }
            }
            pieces.Add(currInfo);
            return(pieces);
        }
예제 #2
0
        private void MakeState(string url, string path)
        {
            // Get general info about the playlist
            string            hls_pl   = Encoding.UTF8.GetString(DownloadDataSafe(url));
            string            hls_base = url.Remove(url.LastIndexOf('/') + 1);
            List <TsFileInfo> pieces   = GetPieces(hls_pl);

            // Run over the file
            long size    = new FileInfo(path).Length;
            long cur_pos = 0;
            int  i       = 0;

            for (i = 0; i < pieces.Count; i++)
            {
                TsFileInfo piece    = pieces[i];
                int        cur_size = 1 + GetOffset(piece.end_offset) - GetOffset(piece.start_offset);
                if (cur_pos + cur_size <= size)
                {
                    cur_pos += cur_size;
                }
                else
                {
                    break;
                }
            }
            if (i == pieces.Count)
            {
                MessageBox.Show("File is complete");
            }
            else
            {
                File.WriteAllBytes(pieces[i - 1].name, DownloadDataUberSafe(pieces[i - 1].MakeUrl(hls_base)));
                SaveState(i, cur_pos);
                MessageBox.Show("Saved state");
            }
        }
예제 #3
0
        private void DownloadPlaylist(string url, string outdir, string id, double ratio, double eratio)
        {
            // Get general info about the playlist
            string            hls_pl   = Encoding.UTF8.GetString(DownloadDataSafe(url));
            string            hls_base = url.Remove(url.LastIndexOf('/') + 1);
            List <TsFileInfo> pieces   = GetPieces(hls_pl);

            // Start GUI features (progressbar and download speed)
            InitProgress(pieces.Count);
            Stopwatch sw = new Stopwatch();

            sw.Start();
            long totBytes = 0;

            // We now have all pieces and need to just download and concat them
            string tspath  = Path.Combine(outdir, id + ".ts");
            int    i_start = 0;
            long   pos     = 0;

            // If there is a backup, try to restore
            if (File.Exists(StateFileName) && MessageBox.Show("Restore backup?", "Backup", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                int[] data = File.ReadAllLines(StateFileName).Select(x => int.Parse(x)).ToArray();
                i_start = data[0];
                pos     = data[1];
            }
            else
            {
                i_start = GetBytePieceIndex(pieces, ratio);
            }
            int i_end = GetBytePieceIndex(pieces, eratio) + 1;

            Log(string.Format("Fast tracked to piece {0}, ending at {1}/{2}", i_start, i_end, pieces.Count));

            // Actual DL
            using (FileStream fs = new FileStream(tspath, pos == 0 ? FileMode.Create : FileMode.Open))
            {
                if (pos != 0)
                {
                    fs.Seek(pos, SeekOrigin.Begin);
                }

                for (int i = 0; i < i_start; i++)
                {
                    AdvanceProgress();
                }

                for (int i = i_start; i < i_end; i++)
                {
                    // Backup our progress
                    SaveState(i, fs.Position);

                    // Download the data
                    TsFileInfo tsInfo = pieces[i];
                    sw.Restart();
                    byte[] data = DownloadDataUberSafe(tsInfo.MakeUrl(hls_base));

                    // Write to file, log and do GUI features
                    totBytes /*+*/ = data.Length;
                    Log("Writing " + data.Length.ToString() + " bytes to position " + fs.Position.ToString());
                    fs.Write(data, 0, data.Length);
                    AdvanceProgress();
                    SetSpeed(totBytes / 1024.0 / 1024.0 / sw.Elapsed.TotalSeconds);
                    Thread.Sleep(sleep);
                }
            }

            // Remove backup file since we finished
            File.Delete(StateFileName);

            // Encoding
            Log("FFMPEG");
            string mp4path = Path.Combine(outdir, id + ".mp4");

            if (File.Exists(mp4path))
            {
                new FileInfo(mp4path).Delete();
            }
            Process.Start("ffmpeg", "-i " + tspath + " -acodec copy -vcodec copy -bsf:a aac_adtstoasc " + mp4path);
            Log("Done.");
        }