Skip to content

Commit

Permalink
Support downloading VODs as audio only (#894)
Browse files Browse the repository at this point in the history
* Support downloading audio from twitch vods

* Update CLI README
  • Loading branch information
ScrubN authored Nov 20, 2023
1 parent f5733d0 commit da7bdfc
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion TwitchDownloaderCLI/Modes/Arguments/VideoDownloadArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class VideoDownloadArgs : ITwitchDownloaderArgs
[Option('u', "id", Required = true, HelpText = "The ID or URL of the VOD to download.")]
public string Id { get; set; }

[Option('o', "output", Required = true, HelpText = "Path to output file.")]
[Option('o', "output", Required = true, HelpText = "Path to output file. File extension will be used to determine download type. Valid extensions are: .mp4 and .m4a.")]
public string OutputFile { get; set; }

[Option('q', "quality", HelpText = "The quality the program will attempt to download.")]
Expand Down
15 changes: 14 additions & 1 deletion TwitchDownloaderCLI/Modes/DownloadVideo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,27 @@ private static VideoDownloadOptions GetDownloadOptions(VideoDownloadArgs inputOp
Environment.Exit(1);
}

if (!Path.HasExtension(inputOptions.OutputFile) && inputOptions.Quality is { Length: > 0 })
{
if (char.IsDigit(inputOptions.Quality[0]))
inputOptions.OutputFile += ".mp4";
else if (char.ToLower(inputOptions.Quality[0]) is 'a')
inputOptions.OutputFile += ".m4a";
}

VideoDownloadOptions downloadOptions = new()
{
DownloadThreads = inputOptions.DownloadThreads,
ThrottleKib = inputOptions.ThrottleKib,
Id = int.Parse(vodIdMatch.ValueSpan),
Oauth = inputOptions.Oauth,
Filename = inputOptions.OutputFile,
Quality = inputOptions.Quality,
Quality = Path.GetExtension(inputOptions.OutputFile)!.ToLower() switch
{
".mp4" => inputOptions.Quality,
".m4a" => "Audio",
_ => throw new ArgumentException("Only MP4 and M4A audio files are supported.")
},
CropBeginning = inputOptions.CropBeginningTime > 0.0,
CropBeginningTime = inputOptions.CropBeginningTime,
CropEnding = inputOptions.CropEndingTime > 0.0,
Expand Down
2 changes: 1 addition & 1 deletion TwitchDownloaderCLI/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ A cross platform command line tool that can do the main functions of the GUI pro
The ID or URL of the VOD to download.

**-o / --output (REQUIRED)**
File the program will output to.
File the program will output to. File extension will be used to determine download type. Valid extensions are: `.mp4` and `.m4a`.

**-q / --quality**
The quality the program will attempt to download, for example "1080p60", if not found will download highest quality stream.
Expand Down
2 changes: 1 addition & 1 deletion TwitchDownloaderCore/TwitchHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static async Task<string[]> GetVideoPlaylist(int videoId, string token, s
{
var request = new HttpRequestMessage()
{
RequestUri = new Uri($"http://usher.ttvnw.net/vod/{videoId}?nauth={token}&nauthsig={sig}&allow_source=true&player=twitchweb"),
RequestUri = new Uri($"http://usher.ttvnw.net/vod/{videoId}?nauth={token}&nauthsig={sig}&allow_audio_only=true&allow_source=true&player=twitchweb"),
Method = HttpMethod.Get
};
request.Headers.Add("Client-ID", "kimne78kx3ncx6brgo4mv6wki5h1ko");
Expand Down
4 changes: 2 additions & 2 deletions TwitchDownloaderCore/VideoDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -585,9 +585,9 @@ private static async Task DownloadVideoPartAsync(HttpClient httpClient, Uri base
}
}

if (downloadOptions.Quality != null && videoQualities.Any(x => x.Key.StartsWith(downloadOptions.Quality)))
if (downloadOptions.Quality != null && videoQualities.Any(x => x.Key.StartsWith(downloadOptions.Quality, StringComparison.OrdinalIgnoreCase)))
{
return videoQualities.Last(x => x.Key.StartsWith(downloadOptions.Quality)).Value;
return videoQualities.Last(x => x.Key.StartsWith(downloadOptions.Quality, StringComparison.OrdinalIgnoreCase)).Value;
}

// Unable to find specified quality, defaulting to highest quality
Expand Down
4 changes: 2 additions & 2 deletions TwitchDownloaderWPF/PageVodDownload.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public VideoDownloadOptions GetOptions(string filename, string folder)
Filename = filename ?? Path.Combine(folder, FilenameService.GetFilename(Settings.Default.TemplateVod, textTitle.Text, currentVideoId.ToString(), currentVideoTime, textStreamer.Text,
checkStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.Zero,
checkEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : vodLength,
viewCount.ToString(), game) + ".mp4"),
viewCount.ToString(), game) + (comboQuality.Text.Contains("Audio", StringComparison.OrdinalIgnoreCase) ? ".m4a" : ".mp4")),
Oauth = TextOauth.Text,
Quality = GetQualityWithoutSize(comboQuality.Text).ToString(),
Id = currentVideoId,
Expand Down Expand Up @@ -402,7 +402,7 @@ private async void SplitBtnDownloader_Click(object sender, RoutedEventArgs e)

SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = "MP4 Files | *.mp4",
Filter = comboQuality.Text.Contains("Audio", StringComparison.OrdinalIgnoreCase) ? "M4A Files | *.m4a" : "MP4 Files | *.mp4",
FileName = FilenameService.GetFilename(Settings.Default.TemplateVod, textTitle.Text, currentVideoId.ToString(), currentVideoTime, textStreamer.Text,
checkStart.IsChecked == true ? new TimeSpan((int)numStartHour.Value, (int)numStartMinute.Value, (int)numStartSecond.Value) : TimeSpan.Zero,
checkEnd.IsChecked == true ? new TimeSpan((int)numEndHour.Value, (int)numEndMinute.Value, (int)numEndSecond.Value) : vodLength,
Expand Down

0 comments on commit da7bdfc

Please sign in to comment.