在 Java 中将视频从我的网络服务器上传到 Youtube
Upload videos to Youtube from my web server in Java
我的目标是将上传到我的网络服务器的视频上传到 我自己的频道 上的 Youtube,而不是用户的 Youtube 帐户(我的网络服务器充当代理)。
我找到了将视频上传到 Youtube 的示例代码 here with the credential acquired this way。我在这个示例中遇到的问题是它将凭据写入磁盘,并打开了一个 http 服务器。由于我的 Web 服务器可能有很多用户同时上传他们的视频,因此凭证文件位置必须是动态的,并且不可能多次绑定到同一个 http 端口。此外,在搜索了其他关于上传到 Youtube 的文章后,我认为这种方法适用于用户上传到他们的 Youtube 帐户。
你能为我的场景分享你的 experiences/code sample/solutions 吗?简而言之,我只是想自动执行打开 Youtube 仪表板并将视频上传到我的 Youtube 频道的过程。
一般来说,从 API V3 开始,Google 比其他机制更喜欢 OAuth2,上传视频(或任何其他修改用户数据的操作)需要 OAuth2。
幸运的是,有一种叫做 refresh token
的特殊令牌可以解决这个问题。刷新令牌不会像普通访问令牌一样过期,用于在需要时生成普通访问令牌。所以,我把我的申请分为两部分:
- 第 1 部分用于生成刷新令牌,它是一个 Java 桌面应用程序,由用户在计算机上 运行 使用。 See here 来自 Google.
的示例代码
- 第二部分是我的 Web 应用程序的一部分,它使用给定的刷新令牌来创建凭据对象。
这是我在 Scala 中的实现,您可以轻松适应 Java 版本:
要生成刷新令牌,您应该将授权流程的 accessType 设置为 offline
。注意:如果您的系统上已经存在一个令牌,它不会尝试获取新令牌,即使它没有刷新令牌,所以您还必须将批准提示设置为 force
:
def authorize(dataStoreName: String, clientId: String, clientSecret: String): Credential = {
val builder = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT,
JSON_FACTORY,
clientId,
clientSecret,
Seq(YouTubeScopes.YOUTUBE_UPLOAD)
)
val CREDENTIAL_DIRECTORY = s"${System.getProperty("user.home")}/.oauth-credentials"
val fileDataStoreFactory = new FileDataStoreFactory(new java.io.File(CREDENTIAL_DIRECTORY))
val dataStore: DataStore[StoredCredential] = fileDataStoreFactory.getDataStore(dataStoreName)
builder.setCredentialDataStore(dataStore).setAccessType("offline").setApprovalPrompt("force")
val flow = builder.build()
val localReceiver = new LocalServerReceiver.Builder().setPort(8000).build()
new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user")
}
val credential = authorize(dataStore, clientId, clientSecret)
val refreshToken = credential.getRefreshToken
要在服务器上使用刷新令牌,您可以从刷新令牌构建凭据:
def getCredential = new GoogleCredential.Builder()
.setJsonFactory(JSON_FACTORY)
.setTransport(HTTP_TRANSPORT)
.setClientSecrets(clientId, clientSecret)
.build()
.setRefreshToken(refreshToken)
我已经绕过了整个 AuthorizationCodeInstalledApp authorize() 方法并创建了一个绕过码头服务器实现过程的新子类。
方法如下
- getAuthorizationFromStorage:从存储的凭据中获取访问令牌。
- getAuthorizationFromGoogle :使用 Google 中的凭据获取身份验证创建 url ,它将引导用户进入身份验证页面并在中创建自定义名称-值对状态参数。该值应使用 base64 编码器进行编码,以便我们可以在身份验证后收到从 google 重定向的相同代码。
saveAuthorizationFromGoogle :保存我们从 google.
获得的凭据
- 根据身份验证后从 google 收到的响应,从 credentialDatastor 创建 GoogleAuthorizationCodeFlow 对象。
- 点击google获取永久刷新令牌,可用于随时获取用户的访问令牌。
- 将文件名中的 accesstoken 和 refreshtoken 等令牌存储为 userid
检查代码实现 here
我的目标是将上传到我的网络服务器的视频上传到 我自己的频道 上的 Youtube,而不是用户的 Youtube 帐户(我的网络服务器充当代理)。
我找到了将视频上传到 Youtube 的示例代码 here with the credential acquired this way。我在这个示例中遇到的问题是它将凭据写入磁盘,并打开了一个 http 服务器。由于我的 Web 服务器可能有很多用户同时上传他们的视频,因此凭证文件位置必须是动态的,并且不可能多次绑定到同一个 http 端口。此外,在搜索了其他关于上传到 Youtube 的文章后,我认为这种方法适用于用户上传到他们的 Youtube 帐户。
你能为我的场景分享你的 experiences/code sample/solutions 吗?简而言之,我只是想自动执行打开 Youtube 仪表板并将视频上传到我的 Youtube 频道的过程。
一般来说,从 API V3 开始,Google 比其他机制更喜欢 OAuth2,上传视频(或任何其他修改用户数据的操作)需要 OAuth2。
幸运的是,有一种叫做 refresh token
的特殊令牌可以解决这个问题。刷新令牌不会像普通访问令牌一样过期,用于在需要时生成普通访问令牌。所以,我把我的申请分为两部分:
- 第 1 部分用于生成刷新令牌,它是一个 Java 桌面应用程序,由用户在计算机上 运行 使用。 See here 来自 Google. 的示例代码
- 第二部分是我的 Web 应用程序的一部分,它使用给定的刷新令牌来创建凭据对象。
这是我在 Scala 中的实现,您可以轻松适应 Java 版本:
要生成刷新令牌,您应该将授权流程的 accessType 设置为 offline
。注意:如果您的系统上已经存在一个令牌,它不会尝试获取新令牌,即使它没有刷新令牌,所以您还必须将批准提示设置为 force
:
def authorize(dataStoreName: String, clientId: String, clientSecret: String): Credential = {
val builder = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT,
JSON_FACTORY,
clientId,
clientSecret,
Seq(YouTubeScopes.YOUTUBE_UPLOAD)
)
val CREDENTIAL_DIRECTORY = s"${System.getProperty("user.home")}/.oauth-credentials"
val fileDataStoreFactory = new FileDataStoreFactory(new java.io.File(CREDENTIAL_DIRECTORY))
val dataStore: DataStore[StoredCredential] = fileDataStoreFactory.getDataStore(dataStoreName)
builder.setCredentialDataStore(dataStore).setAccessType("offline").setApprovalPrompt("force")
val flow = builder.build()
val localReceiver = new LocalServerReceiver.Builder().setPort(8000).build()
new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user")
}
val credential = authorize(dataStore, clientId, clientSecret)
val refreshToken = credential.getRefreshToken
要在服务器上使用刷新令牌,您可以从刷新令牌构建凭据:
def getCredential = new GoogleCredential.Builder()
.setJsonFactory(JSON_FACTORY)
.setTransport(HTTP_TRANSPORT)
.setClientSecrets(clientId, clientSecret)
.build()
.setRefreshToken(refreshToken)
我已经绕过了整个 AuthorizationCodeInstalledApp authorize() 方法并创建了一个绕过码头服务器实现过程的新子类。 方法如下
- getAuthorizationFromStorage:从存储的凭据中获取访问令牌。
- getAuthorizationFromGoogle :使用 Google 中的凭据获取身份验证创建 url ,它将引导用户进入身份验证页面并在中创建自定义名称-值对状态参数。该值应使用 base64 编码器进行编码,以便我们可以在身份验证后收到从 google 重定向的相同代码。
saveAuthorizationFromGoogle :保存我们从 google.
获得的凭据- 根据身份验证后从 google 收到的响应,从 credentialDatastor 创建 GoogleAuthorizationCodeFlow 对象。
- 点击google获取永久刷新令牌,可用于随时获取用户的访问令牌。
- 将文件名中的 accesstoken 和 refreshtoken 等令牌存储为 userid
检查代码实现 here