Skip to content

Instantly share code, notes, and snippets.

@siketyan
Created December 9, 2018 06:26
Show Gist options
  • Save siketyan/89c48d6bc9396cce2983736ba8036551 to your computer and use it in GitHub Desktop.
Save siketyan/89c48d6bc9396cce2983736ba8036551 to your computer and use it in GitHub Desktop.
Twitcasting Recorded Live Downloader with Password (Requires AngleSharp)
/*
*
* The MIT License (MIT)
*
* Copyright (C) 2018 Siketyan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
using AngleSharp.Dom.Html;
using AngleSharp.Parser.Html;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace Recast
{
public class Program
{
public static async Task Main(string[] args)
{
var src = args[0];
var dest = args[1];
var password = args.Length >= 3 ? args[2] : null;
var payload = new FormUrlEncodedContent(
new Dictionary<string, string>
{
{ "password", password }
}
);
Console.WriteLine($"Source: {src}");
Console.WriteLine($"Destination: {dest}");
Console.WriteLine($"Password: {password}");
Console.WriteLine();
if (File.Exists(dest))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("! Error: File already exists");
Console.ResetColor();
return;
}
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("> Reading metadata");
var doc = default(IHtmlDocument);
using (var client = new HttpClient())
using (var response = await client.PostAsync(src, payload))
using (var stream = await response.Content.ReadAsStreamAsync())
{
var parser = new HtmlParser();
doc = await parser.ParseAsync(stream);
}
var player = doc.GetElementById("player");
var m3u8 = player.GetAttribute("data-movie-url");
Erase();
Console.WriteLine($"> Reading playlist: {Path.GetFileName(m3u8)}");
using (var client = new HttpClient())
using (var stream = await client.GetStreamAsync(m3u8))
using (var reader = new StreamReader(stream))
using (var output = File.Open(dest, FileMode.Append))
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync();
if (line.StartsWith('#'))
{
continue;
}
var uri = m3u8.Replace("index.m3u8", line);
Erase();
Console.WriteLine($"> Reading segment: {Path.GetFileName(uri)}");
using (var input = await client.GetStreamAsync(uri))
{
await input.CopyToAsync(output);
}
}
}
Erase();
Console.WriteLine("> Done");
Console.ResetColor();
}
private static void Erase()
{
Console.CursorVisible = false;
Console.CursorTop--;
Console.CursorLeft = 0;
Console.Write(new string(' ', Console.WindowWidth - 1));
Console.CursorLeft = 0;
Console.CursorVisible = true;
}
}
}
@kkyoongi
Copy link

can you please help me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment