Skip to content

Instantly share code, notes, and snippets.

@Mordo95
Last active October 21, 2017 11:13
Show Gist options
  • Save Mordo95/3dcdf60594ff6f0968eb8ebeaf070e19 to your computer and use it in GitHub Desktop.
Save Mordo95/3dcdf60594ff6f0968eb8ebeaf070e19 to your computer and use it in GitHub Desktop.
Streams youtube live to Ffmpeg
//Created by Spike2147 (Mordecaii95 on Github)
//Please credit if you use!
//If this goes in violation of any terms and conditions, please contact me directly.
public class YoutubeLive
{
//src: https://gist.github.com/Boztown/8060963
public static string IdFromUrl(string url)
{
return Regex.Match(url, @"(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^""&?\/ ]{11})").Groups[1].Value;
}
private static async Task<string> GetM3U8(string id, int quality = 95)
{
HttpClient client = new HttpClient();
string m3u8 = HttpUtility.HtmlDecode(await client.GetStringAsync($"https://www.youtube.com/get_video_info?&video_id={id}&el=info&ps=default&eurl=&gl=US&hl=en"));
NameValueCollection nvc = HttpUtility.ParseQueryString(m3u8);
m3u8 = await client.GetStringAsync(nvc["hlsvp"]);
string[] split = m3u8.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
string url = "";
for (int i = 0; i < split.Length; i++)
{
if (!split[i].StartsWith("#EXT-X-STREAM-INF"))
continue;
Dictionary<string, string> m3uparams = M3U8Params(split[i]);
if (!m3uparams["codecs"].Contains("mp4"))
continue;
if (GetITag(split[i + 1]) != quality)
continue;
url = split[i + 1];
break;
}
return url;
}
private static int GetITag(string url)
{
return int.Parse(Regex.Match(url, @"itag/(\d+)").Groups[1].Value);
}
private static Dictionary<string, string> M3U8Params(string extstream)
{
return Regex.Split(extstream.Replace("#EXT-X-STREAM-INF:", ""), ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)").Where(x => !string.IsNullOrEmpty(x)).Select(value => value.Split('=')).ToDictionary(pair => pair[0].ToLower(), pair => pair[1].Replace("\"", ""));
}
public static async Task<Process> GetFfmpeg(string url)
{
string id = IdFromUrl(url);
string m3u = await GetM3U8(id);
ProcessStartInfo ffmpeg = new ProcessStartInfo
{
FileName = "ffmpeg",
//Arguments = $"-xerror -i \"{m3u}\" -ac 2 -f s16le -ar 48000 pipe:1",
Arguments = $"-xerror -i \"{m3u}\" -c copy -bsf:a aac_adtstoasc output.mp4",
UseShellExecute = false,
RedirectStandardOutput = true
};
return Process.Start(ffmpeg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment