diff --git a/TwitchDownloaderCore/ChatDownloader.cs b/TwitchDownloaderCore/ChatDownloader.cs index 1a701a72..f0d560db 100644 --- a/TwitchDownloaderCore/ChatDownloader.cs +++ b/TwitchDownloaderCore/ChatDownloader.cs @@ -257,6 +257,24 @@ public async Task DownloadAsync(CancellationToken cancellationToken) // Open the destination file so that it exists in the filesystem. await using var outputFs = outputFileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + await DownloadAsyncImpl(outputFileInfo, outputFs, cancellationToken); + } + catch + { + outputFileInfo.Refresh(); + if (outputFileInfo.Exists && outputFileInfo.Length == 0) + { + outputFileInfo.Delete(); + } + + throw; + } + } + + private async Task DownloadAsyncImpl(FileInfo outputFileInfo, FileStream outputFs, CancellationToken cancellationToken) + { DownloadType downloadType = downloadOptions.Id.All(char.IsDigit) ? DownloadType.Video : DownloadType.Clip; var (chatRoot, connectionCount) = await InitChatRoot(downloadType); diff --git a/TwitchDownloaderCore/ChatRenderer.cs b/TwitchDownloaderCore/ChatRenderer.cs index 6e04f6e9..d9373a07 100644 --- a/TwitchDownloaderCore/ChatRenderer.cs +++ b/TwitchDownloaderCore/ChatRenderer.cs @@ -79,6 +79,33 @@ public async Task RenderVideoAsync(CancellationToken cancellationToken) await using var outputFs = outputFileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.Read); await using var maskFs = maskFileInfo?.Open(FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + await RenderAsyncImpl(outputFileInfo, outputFs, maskFileInfo, maskFs, cancellationToken); + } + catch + { + outputFileInfo.Refresh(); + if (outputFileInfo.Exists && outputFileInfo.Length == 0) + { + outputFileInfo.Delete(); + } + + if (maskFileInfo is not null) + { + maskFileInfo.Refresh(); + if (maskFileInfo.Exists && maskFileInfo.Length == 0) + { + maskFileInfo.Delete(); + } + } + + throw; + } + } + + private async Task RenderAsyncImpl(FileInfo outputFileInfo, FileStream outputFs, FileInfo maskFileInfo, FileStream maskFs, CancellationToken cancellationToken) + { _progress.SetStatus("Fetching Images [1/2]"); await Task.Run(() => FetchScaledImages(cancellationToken), cancellationToken); diff --git a/TwitchDownloaderCore/ChatUpdater.cs b/TwitchDownloaderCore/ChatUpdater.cs index 324b5a8f..0eb70329 100644 --- a/TwitchDownloaderCore/ChatUpdater.cs +++ b/TwitchDownloaderCore/ChatUpdater.cs @@ -38,6 +38,24 @@ public async Task UpdateAsync(CancellationToken cancellationToken) // Open the destination file so that it exists in the filesystem. await using var outputFs = outputFileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + await UpdateAsyncImpl(outputFileInfo, outputFs, cancellationToken); + } + catch + { + outputFileInfo.Refresh(); + if (outputFileInfo.Exists && outputFileInfo.Length == 0) + { + outputFileInfo.Delete(); + } + + throw; + } + } + + private async Task UpdateAsyncImpl(FileInfo outputFileInfo, FileStream outputFs, CancellationToken cancellationToken) + { chatRoot.FileInfo = new() { Version = ChatRootVersion.CurrentVersion, CreatedAt = chatRoot.FileInfo.CreatedAt, UpdatedAt = DateTime.Now }; if (!Path.GetExtension(_updateOptions.InputFile.Replace(".gz", ""))!.Equals(".json", StringComparison.OrdinalIgnoreCase)) { diff --git a/TwitchDownloaderCore/ClipDownloader.cs b/TwitchDownloaderCore/ClipDownloader.cs index 72755acc..bf6a91f6 100644 --- a/TwitchDownloaderCore/ClipDownloader.cs +++ b/TwitchDownloaderCore/ClipDownloader.cs @@ -37,6 +37,24 @@ public async Task DownloadAsync(CancellationToken cancellationToken) // Open the destination file so that it exists in the filesystem. await using var outputFs = outputFileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + await DownloadAsyncImpl(outputFileInfo, outputFs, cancellationToken); + } + catch + { + outputFileInfo.Refresh(); + if (outputFileInfo.Exists && outputFileInfo.Length == 0) + { + outputFileInfo.Delete(); + } + + throw; + } + } + + private async Task DownloadAsyncImpl(FileInfo outputFileInfo, FileStream outputFs, CancellationToken cancellationToken) + { _progress.SetStatus("Fetching Clip Info"); var downloadUrl = await GetDownloadUrl(); diff --git a/TwitchDownloaderCore/TsMerger.cs b/TwitchDownloaderCore/TsMerger.cs index 8c44cdba..b119eb81 100644 --- a/TwitchDownloaderCore/TsMerger.cs +++ b/TwitchDownloaderCore/TsMerger.cs @@ -32,6 +32,24 @@ public async Task MergeAsync(CancellationToken cancellationToken) // Open the destination file so that it exists in the filesystem. await using var outputFs = outputFileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + await MergeAsyncImpl(outputFs, cancellationToken); + } + catch + { + outputFileInfo.Refresh(); + if (outputFileInfo.Exists && outputFileInfo.Length == 0) + { + outputFileInfo.Delete(); + } + + throw; + } + } + + private async Task MergeAsyncImpl(FileStream outputFs, CancellationToken cancellationToken) + { var isM3U8 = false; var isFirst = true; var fileList = new List(); diff --git a/TwitchDownloaderCore/VideoDownloader.cs b/TwitchDownloaderCore/VideoDownloader.cs index 5a109a3a..042dfcd9 100644 --- a/TwitchDownloaderCore/VideoDownloader.cs +++ b/TwitchDownloaderCore/VideoDownloader.cs @@ -45,6 +45,24 @@ public async Task DownloadAsync(CancellationToken cancellationToken) // Open the destination file so that it exists in the filesystem. await using var outputFs = outputFileInfo.Open(FileMode.Create, FileAccess.Write, FileShare.Read); + try + { + await DownloadAsyncImpl(outputFileInfo, outputFs, cancellationToken); + } + catch + { + outputFileInfo.Refresh(); + if (outputFileInfo.Exists && outputFileInfo.Length == 0) + { + outputFileInfo.Delete(); + } + + throw; + } + } + + private async Task DownloadAsyncImpl(FileInfo outputFileInfo, FileStream outputFs, CancellationToken cancellationToken) + { await TwitchHelper.CleanupAbandonedVideoCaches(downloadOptions.TempFolder, downloadOptions.CacheCleanerCallback, _progress); string downloadFolder = Path.Combine(