You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:44:16