基于Node.js代用户上传YouTube Shorts离线视频的技术问询
YouTube Shorts 代上传代码问题与修复指导
我需要代用户上传YouTube Shorts短视频,认证流程已在Web应用中完成,token和refresh token存储在数据库里,后续通过脚本从数据库获取凭证完成视频上传。但Node.js googleapis库官方文档不够全面,附上现有代码寻求技术指导:
let tokens = { access_token: data.youtube_token, refresh_token: data.youtube_refresh_token } const oauth2Client = new OAuth2( 'my-credentials', 'my-credentials', 'https://myapp.com/api/google/oauth2callback' ); oauth2Client.credentials = data.youtube_token const service = google.youtube('v3') let title = 'Testing #Shorts' let description = 'Testing description #Shorts' let tags = '#short' let videoFilePath = 'link-to-video' const downloadStream = got.stream(videoFilePath); service.videos.insert({ auth: oauth2Client.credentials, part: 'snippet,status', requestBody: { snippet: { title, description, defaultLanguage: 'en', defaultAudioLanguage: 'en' }, status: { privacyStatus: "private" }, }, media: { body: downloadStream, }, }, function(err, response) { if (err) { console.log('The API returned an error: ' + err); return; } console.log(response.data) console.log('Video uploaded. Uploading the thumbnail now.') /* service.thumbnails.set({ auth: auth, videoId: response.data.id, media: { body: fs.createReadStream(thumbFilePath) }, }, function(err, response) { if (err) { console.log('The API returned an error: ' + err); return; } console.log(response.data) }) */ });
代码问题与修复方案
OAuth2凭证赋值错误:原代码中
oauth2Client.credentials = data.youtube_token仅传入单个access_token,正确做法是传入包含access_token和refresh_token的完整tokens对象,这样客户端才能自动刷新过期的access_token:oauth2Client.credentials = tokens;认证参数传递错误:
service.videos.insert的auth字段应传入完整的oauth2Client实例,而非oauth2Client.credentials。googleapis库需要通过客户端实例处理token刷新等逻辑:auth: oauth2Client,Shorts标识配置缺失:要让视频被识别为YouTube Shorts,需满足两个核心条件:视频本身为9:16竖屏比例;同时在代码中完善snippet配置:
- 将tags改为数组格式(API要求tags为字符串数组)
- 添加对应分类ID(Shorts常用分类为娱乐类
22)
修改后的snippet部分:
snippet: { title, description, tags: ['#Shorts', '#short'], categoryId: '22', defaultLanguage: 'en', defaultAudioLanguage: 'en' },缩略图上传的认证问题:注释中的缩略图上传代码里
auth: auth未定义,应替换为oauth2Client,同时确保thumbFilePath指向正确的本地文件路径:service.thumbnails.set({ auth: oauth2Client, videoId: response.data.id, media: { body: fs.createReadStream(thumbFilePath) }, }, function(err, response) { if (err) { console.log('The API returned an error: ' + err); return; } console.log('Thumbnail uploaded:', response.data) })
修复后的完整代码
const { google } = require('googleapis'); const { OAuth2 } = google.auth; const got = require('got'); const fs = require('fs'); // 从数据库获取凭证 const data = { /* 数据库返回的包含youtube_token和youtube_refresh_token的对象 */ }; let tokens = { access_token: data.youtube_token, refresh_token: data.youtube_refresh_token }; const oauth2Client = new OAuth2( '你的客户端ID', '你的客户端密钥', 'https://myapp.com/api/google/oauth2callback' ); // 正确赋值完整凭证 oauth2Client.credentials = tokens; const service = google.youtube('v3'); let title = 'Testing #Shorts'; let description = 'Testing description #Shorts'; let tags = ['#Shorts', '#short']; let videoFilePath = 'link-to-video'; const downloadStream = got.stream(videoFilePath); const thumbFilePath = 'path-to-thumbnail-image'; // 缩略图路径 service.videos.insert({ auth: oauth2Client, part: 'snippet,status', requestBody: { snippet: { title, description, tags, categoryId: '22', defaultLanguage: 'en', defaultAudioLanguage: 'en' }, status: { privacyStatus: "private" }, }, media: { body: downloadStream, }, }, function(err, response) { if (err) { console.log('视频上传API错误: ' + err); return; } console.log('视频上传成功:', response.data); console.log('开始上传缩略图...'); service.thumbnails.set({ auth: oauth2Client, videoId: response.data.id, media: { body: fs.createReadStream(thumbFilePath) }, }, function(err, thumbResponse) { if (err) { console.log('缩略图上传API错误: ' + err); return; } console.log('缩略图上传成功:', thumbResponse.data); }); });
内容的提问来源于stack exchange,提问作者Peter Utekal
相关产品推荐
相关产品推荐

