如何从TXT逐行提取歌曲名,调用异步函数批量处理YouTube播放列表
批量处理TXT歌曲名并添加到YouTube播放列表
需求说明
我有一个每行存储一首歌曲名的TXT文件,希望自动逐行提取每个歌曲名,完成以下操作:
- 通过YouTube Data API v3搜索歌曲获取对应视频ID
- 将视频ID添加到指定YouTube播放列表
当前代码只能手动输入单个歌曲名到TextBox1,需要修改为支持批量处理至少200首歌曲。
当前代码
Imports System Imports System.IO Imports System.Reflection Imports System.Threading Imports System.Threading.Tasks Imports Google.Apis.Auth.OAuth2 Imports Google.Apis.Services Imports Google.Apis.Upload Imports Google.Apis.Util.Store Imports Google.Apis.YouTube.v3 Imports Google.Apis.YouTube.v3.Data Public Class Form1 Public id As String Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try Await RetrieveID() Await PlaylistUpdates() Catch ex As AggregateException For Each inner In ex.InnerExceptions MsgBox("Error: " & inner.Message) Next End Try End Sub Private Async Function RetrieveID() As Task Dim youtubeService = New YouTubeService(New BaseClientService.Initializer() With { .ApiKey = "my api key ", .ApplicationName = Me.[GetType]().ToString() }) Dim searchListRequest = youtubeService.Search.List("snippet") searchListRequest.Q = TextBox1.Text searchListRequest.MaxResults = 1 Dim searchListResponse = Await searchListRequest.ExecuteAsync() For Each searchResult In searchListResponse.Items id = searchResult.Id.VideoId Next MsgBox(id) End Function Private Async Function PlaylistUpdates() As Task Dim credential As UserCredential Using stream = New FileStream("client_secret_697184292163-n9c9etf5arv7iqkq6f84tlfqmjtfqi9g.apps.googleusercontent.com.json", FileMode.Open, FileAccess.Read) credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.FromStream(stream).Secrets, {YouTubeService.Scope.Youtube}, "user", CancellationToken.None, New FileDataStore(Me.[GetType]().ToString())) End Using Dim youtubeServiceo = New YouTubeService(New BaseClientService.Initializer() With { .HttpClientInitializer = credential, .ApplicationName = Me.[GetType]().ToString() }) Dim newPlaylistItem = New PlaylistItem() newPlaylistItem.Snippet = New PlaylistItemSnippet() newPlaylistItem.Snippet.PlaylistId = "PL4_Dx88dpu7cEY_cBjTZFFM1tVKF5Plsx" newPlaylistItem.Snippet.ResourceId = New ResourceId() newPlaylistItem.Snippet.ResourceId.Kind = "youtube#video" newPlaylistItem.Snippet.ResourceId.VideoId = id newPlaylistItem = Await youtubeServiceo.PlaylistItems.Insert(newPlaylistItem, "snippet").ExecuteAsync() MsgBox(id + " è stato inserito nella playlist") End Function End Class
修改后的代码(支持批量处理)
Imports System Imports System.IO Imports System.Reflection Imports System.Threading Imports System.Threading.Tasks Imports Google.Apis.Auth.OAuth2 Imports Google.Apis.Services Imports Google.Apis.Upload Imports Google.Apis.Util.Store Imports Google.Apis.YouTube.v3 Imports Google.Apis.YouTube.v3.Data Public Class Form1 ' 提取常量便于维护 Private Const API_KEY As String = "my api key " Private Const CLIENT_SECRET_PATH As String = "client_secret_697184292163-n9c9etf5arv7iqkq6f84tlfqmjtfqi9g.apps.googleusercontent.com.json" Private Const PLAYLIST_ID As String = "PL4_Dx88dpu7cEY_cBjTZFFM1tVKF5Plsx" ' 复用服务实例,减少初始化开销 Private _youtubeSearchService As YouTubeService Private _youtubePlaylistService As YouTubeService Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' 初始化YouTube服务 Await InitializeYouTubeServices() ' 选择目标TXT文件 Using openFileDialog As New OpenFileDialog() openFileDialog.Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*" If openFileDialog.ShowDialog() = DialogResult.OK Then Dim songNames = File.ReadAllLines(openFileDialog.FileName) Dim successCount = 0 Dim failCount = 0 ' 逐行处理歌曲 For Each songName In songNames If String.IsNullOrWhiteSpace(songName) Then Continue For Try ' 获取视频ID Dim videoId = Await RetrieveVideoId(songName) If String.IsNullOrEmpty(videoId) Then failCount += 1 MsgBox($"未找到歌曲「{songName}」的对应视频") Continue For End If ' 添加到播放列表 Await AddVideoToPlaylist(videoId) successCount += 1 MsgBox($"歌曲「{songName}」已成功添加到播放列表") Catch ex As Exception failCount += 1 MsgBox($"处理歌曲「{songName}」出错: {ex.Message}") End Try Next ' 批量处理完成提示 MsgBox($"批量处理结束!成功添加 {successCount} 首,失败 {failCount} 首") End If End Using End Sub ' 初始化YouTube服务实例 Private Async Function InitializeYouTubeServices() As Task ' 搜索服务(仅需API Key) _youtubeSearchService = New YouTubeService(New BaseClientService.Initializer() With { .ApiKey = API_KEY, .ApplicationName = Me.GetType().ToString() }) ' 播放列表操作服务(需OAuth授权) Dim credential As UserCredential Using stream = New FileStream(CLIENT_SECRET_PATH, FileMode.Open, FileAccess.Read) credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.FromStream(stream).Secrets, {YouTubeService.Scope.Youtube}, "user", CancellationToken.None, New FileDataStore(Me.GetType().ToString()) ) End Using _youtubePlaylistService = New YouTubeService(New BaseClientService.Initializer() With { .HttpClientInitializer = credential, .ApplicationName = Me.GetType().ToString() }) End Function ' 根据歌曲名获取视频ID Private Async Function RetrieveVideoId(songName As String) As Task(Of String) Dim searchRequest = _youtubeSearchService.Search.List("snippet") searchRequest.Q = songName searchRequest.MaxResults = 1 searchRequest.Type = "video" ' 仅搜索视频,排除频道、播放列表 Dim searchResponse = Await searchRequest.ExecuteAsync() Return If(searchResponse.Items.Count > 0, searchResponse.Items(0).Id.VideoId, Nothing) End Function ' 将视频添加到指定播放列表 Private Async Function AddVideoToPlaylist(videoId As String) As Task Dim playlistItem = New PlaylistItem() playlistItem.Snippet = New PlaylistItemSnippet() playlistItem.Snippet.PlaylistId = PLAYLIST_ID playlistItem.Snippet.ResourceId = New ResourceId() playlistItem.Snippet.ResourceId.Kind = "youtube#video" playlistItem.Snippet.ResourceId.VideoId = videoId Await _youtubePlaylistService.PlaylistItems.Insert(playlistItem, "snippet").ExecuteAsync() End Function End Class
关键改动说明
- 移除全局变量:替换为函数参数,避免批量处理时的变量冲突
- 服务实例复用:仅初始化一次YouTube服务,提升处理效率
- 批量读取逻辑:通过文件选择框读取TXT文件内容,逐行处理歌曲
- 异常隔离:单个歌曲处理失败不中断整体任务,记录失败数量
- 搜索优化:指定搜索类型为视频,避免返回无效结果
- 常量提取:将硬编码的配置项提取为常量,便于后续修改维护
内容的提问来源于stack exchange,提问作者adato adaue
相关产品推荐
相关产品推荐

