public VideoRowChangeEvent(VideoRow row, global::System.Data.DataRowAction action)
 {
     this.eventRow    = row;
     this.eventAction = action;
 }
Пример #2
0
        public static async Task <int> Main(
            IConsole console,
            string?twitchUserId           = null,
            string?twitchClientId         = null,
            string?twitchClientSecret     = null,
            string?azureStorageAccountKey = null,
            string?youTubeUsername        = null,
            string?youTubePassword        = null,
            string?youTubeRecoveryEmail   = null)
        {
            var configBuilder = new ConfigurationBuilder();

            configBuilder.AddEnvironmentVariables();
            configBuilder.AddUserSecrets(typeof(Program).Assembly);
            var config  = configBuilder.Build();
            var section = config.GetSection(nameof(VideoConverter));

            twitchUserId ??= section["TwitchUserId"] ?? throw new InvalidOperationException("No Twitch user id specified");
            twitchClientId ??= section["TwitchClientId"] ?? throw new InvalidOperationException("No Twitch client id specified");
            twitchClientSecret ??= section["TwitchClientSecret"] ?? throw new InvalidOperationException("No Twitch client secret specified");

            var storageAccount       = StorageAccount.Get(azureStorageAccountKey, config);
            var tableClient          = storageAccount.CreateCloudTableClient();
            var streamVideoTables    = tableClient.GetTableReference("streamvideos");
            var youtubeSettingsTable = tableClient.GetTableReference("youtubesettings");

            TwitchAPI api = new(settings : new ApiSettings()
            {
                ClientId = twitchClientId,
                Secret = twitchClientSecret
            });

            var httpClient   = new HttpClient();
            var twitchClinet = new Twitch(httpClient);

            console.Out.WriteLine("Retrieving videos from twitch");
            var videoResponse = await api.Helix.Videos.GetVideoAsync(userId : twitchUserId);

            foreach (TwitchVideo video in videoResponse.Videos)
            {
                // Check if video exists in storage
                VideoRow?row = streamVideoTables.CreateQuery <VideoRow>()
                               .Where(x => x.TwitchVideoId == video.Id)
                               .FirstOrDefault();
                if (!string.IsNullOrWhiteSpace(row?.YouTubeVideoId))
                {
                    console.Out.WriteLine($"Twitch video {video.Id} already has YouTube id '{row.YouTubeVideoId}'; skipping");
                    continue;
                }
                console.Out.WriteLine($"Downloading '{video.Title}' from {video.CreatedAt} - {video.Id} ");

                FileInfo?downloadedFilePath = await twitchClinet.DownloadVideoFileAsync(video.Id);

                if (downloadedFilePath is null)
                {
                    console.Out.WriteLine($"Failed to download video file");
                    return(1);
                }
                console.Out.WriteLine($"Downloaded video to '{downloadedFilePath}'");

                FileInfo?trimmedFilePath = await Ffmpeg.TrimLeadingSilence(downloadedFilePath);

                if (trimmedFilePath is null)
                {
                    console.Error.WriteLine($"Failed to trim silence from '{downloadedFilePath}'");
                    return(1);
                }
                console.Out.WriteLine($"Trimmed silence '{trimmedFilePath}'");

                var youtubeSection      = config.GetSection("YouTube");
                BrowserCredential creds = new(
                    youTubeUsername ?? youtubeSection["Username"],
                    youTubePassword ?? youtubeSection["Password"],
                    youTubeRecoveryEmail ?? youtubeSection["RecoveryEmail"]);
                string youTubeId = await UploadVideoAsync(creds, trimmedFilePath, video);
                await DeleteFile(trimmedFilePath);

                if (string.IsNullOrWhiteSpace(youTubeId))
                {
                    console.Error.WriteLine($"Failed to upload '{trimmedFilePath}'");
                    return(1);
                }
                console.Out.WriteLine($"Uploaded to YouTube '{youTubeId}'");


                DateTime recordingDate = video.GetRecordingDate() ?? DateTime.UtcNow.Date;
                if (row is null)
                {
                    row = new VideoRow
                    {
                        PartitionKey = recordingDate.Year.ToString(),
                    };
                }

                row.TwitchVideoId     = video.Id;
                row.TwitchPublishedAt = recordingDate;
                row.YouTubeVideoId    = youTubeId;
                TableOperation insertOperation = TableOperation.InsertOrMerge(row);

                // Execute the operation.
                TableResult _ = await streamVideoTables.ExecuteAsync(insertOperation);

                break;
            }
            return(0);
        }