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

基于ASP.NET的Google API网站端YouTube上传进度显示问题求助

Hey Gary, 当然可以通过异步调用来实现上传进度、完成状态和错误信息的页面展示!你用的那个可恢复上传示例其实已经内置了捕获进度与状态的钩子,只是没做页面呈现而已。我结合你的场景(用户在网站独立登录,但视频上传至你们的企业YouTube账号),给你拆解具体的解决方案:

一、利用异步上传的事件钩子捕获状态

那个ResumableUpload异步实例自带ProgressChanged和Completed事件,你只需要订阅这两个事件,就能实时获取上传数据,再同步到前端页面:

1. 订阅事件并发起异步上传(VB代码)

' 创建ResumableUpload实例(按你现有代码初始化)
Dim upload As New ResumableUpload(...)

' 订阅进度变化事件
AddHandler upload.ProgressChanged, AddressOf Upload_ProgressChanged
' 订阅上传完成/错误事件
AddHandler upload.Completed, AddressOf Upload_Completed

' 启动异步上传
Await upload.UploadAsync()

2. 实现事件处理方法(更新页面UI)

注意Web环境下更新UI需要通过前端脚本注入(以ASP.NET WebForms为例):

Private Sub Upload_ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
    ' 计算上传进度百分比
    Dim progressPercent As Integer = CInt((e.BytesSent / e.TotalBytesToSend) * 100)
    ' 调用前端JS更新进度条
    ScriptManager.RegisterStartupScript(Me, Me.GetType(), "updateProgress", $"updateProgress({progressPercent});", True)
End Sub

Private Sub Upload_Completed(sender As Object, e As Google.Apis.Upload.ResumableUploadCompletedEventArgs(Of Video))
    If e.Error IsNot Nothing Then
        ' 上传出错,展示错误信息
        ScriptManager.RegisterStartupScript(Me, Me.GetType(), "uploadError", $"showError('{HttpUtility.JavaScriptStringEncode(e.Error.Message)}');", True)
    Else
        ' 上传成功,展示完成状态
        ScriptManager.RegisterStartupScript(Me, Me.GetType(), "uploadSuccess", "showSuccess('视频上传完成!');", True)
    End If
End Sub

3. 前端配套JS(页面中添加)

// 更新进度条
function updateProgress(percentage) {
    const progressBar = document.getElementById('uploadProgressBar');
    const progressText = document.getElementById('progressText');
    progressBar.style.width = percentage + '%';
    progressText.textContent = `${percentage}% 已完成`;
}

// 展示错误信息
function showError(message) {
    const statusArea = document.getElementById('statusMessage');
    statusArea.innerHTML = `<span style="color: #dc3545;">上传失败:${message}</span>`;
}

// 展示成功状态
function showSuccess(message) {
    const statusArea = document.getElementById('statusMessage');
    statusArea.innerHTML = `<span style="color: #28a745;">${message}</span>`;
}

二、针对你的OAuth2场景的关键优化

你提到用户有独立网站账号,但视频要传到你们的企业YouTube账号,这里要注意:
不要让用户授权你们的YouTube账号(会导致权限泄露),应该改用**服务账号(Service Account)**实现服务器端上传:

  • 在Google Cloud Console创建服务账号,授予YouTube Data API的操作权限;
  • 在YouTube Studio里把该服务账号添加为你们企业频道的管理员;
  • 服务器端用服务账号凭据完成上传,用户只需要在你们网站登录,无需授权Google账号。

这种方式下,上传逻辑完全在服务器端执行,你依然可以通过上述事件钩子捕获状态并同步到前端。

三、如果Web环境下异步事件失效的备选方案

如果因为Web页面生命周期问题,异步事件无法触发UI更新,可以改用后台任务+前端轮询的方式:

  1. 发起上传时,给每个任务分配唯一ID,把进度、完成状态、错误信息存在Session或数据库中;
  2. 前端用JS定时(比如每秒)发送AJAX请求到服务器,获取该任务的最新状态;
  3. 服务器端返回状态后,前端更新UI。

举个简化的服务器端API示例:

<WebMethod>
Public Shared Function GetUploadStatus(taskId As String) As UploadStatus
    ' 从Session中获取任务状态(也可存在数据库)
    Return DirectCast(HttpContext.Current.Session($"UploadTask_{taskId}"), UploadStatus)
End Function

' 状态实体类
Public Class UploadStatus
    Public Property ProgressPercent As Integer
    Public Property IsCompleted As Boolean
    Public Property ErrorMsg As String
End Class

前端轮询JS:

function startPolling(taskId) {
    const pollInterval = setInterval(() => {
        $.ajax({
            url: 'UploadPage.aspx/GetUploadStatus',
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify({ taskId: taskId }),
            success: function(res) {
                const status = res.d;
                updateProgress(status.ProgressPercent);
                if (status.IsCompleted) {
                    clearInterval(pollInterval);
                    status.ErrorMsg ? showError(status.ErrorMsg) : showSuccess('上传完成!');
                }
            }
        });
    }, 1000);
}

这种方式兼容性更强,能适配大部分Web框架的生命周期限制。

内容的提问来源于stack exchange,提问作者Gary Brownjohn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:36:45