对接YouTube平台实现上传视频——Java实现

这篇具有很好参考价值的文章主要介绍了对接YouTube平台实现上传视频——Java实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景描述

前段时间公司要求对接海外YouTube平台实现视频上传的功能,由于海外文档描述不详细,且本人英语功底不好,过程中踩了很多坑,写出这篇文章出来希望能帮助到有需要的人。

对接YouTube平台的准备

开发环境:idea 、jdk1.8、maven

开发准备

  1. 需要一个Google账号
  2. 需要登录到Google控制台创建应用开启YouTube平台Api
  3. 需要需要去Google控制台下载client_secrets.json文件

下面是图文教程:

  1. Google控制台 创建应用
    java上传视频接口,java,maven,开发语言1.1 选择应用类型
    java上传视频接口,java,maven,开发语言1.2 client_secrets.json文件
    java上传视频接口,java,maven,开发语言2.开启YouTube的Api
    java上传视频接口,java,maven,开发语言2.1 启用此api
    java上传视频接口,java,maven,开发语言环境准备好后咱们先了解一下接入流程

接入流程

调用YouTube Api需要用到Google OAuth2.0 授权,授权完成之后Google会返回给你一个访问令牌,在令牌有效期内可以访问Google Api 而 YouTube Api就是Google Api 下的一种。
下面来看下Google OAuth2.0的授权流程:

  1. 应用向Google oaAuth2服务器发起对用户对该应用的授权请求,利用Google Api返回给应用一个用于用户给应用授权的链接
  2. 用户在浏览器打开授权链接后选择授权给应用的权限后点击确定,Google oaAuth2会回调该应用配置在谷歌后台的回调地址
  3. Google oaAuth服务器回调应用接口会返回用户授权码(code)以及用户给应用赋予的权限(scope),应用拿到用户授权码之后向GoogleoaAuth服务器发起请求把用户授权码兑换成令牌
  4. 拿到oaAuth服务器返回的令牌之后就能够访问YouTube的API了,这里要注意Google oaAuth2服务器返回的令牌是有时间限制的在谷歌后台可以设置过期时间,当令牌过期后需要拿着Google oaAuth2令牌里面的refresh_token向Google oaAuth2服务器重新申请令牌

java上传视频接口,java,maven,开发语言了解完流程之后咱们可以正式进入开发了

代码开发

  1. maven坐标
<!-- maven 坐标 -->
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-youtube</artifactId>
            <version>v3-rev222-1.25.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-client</groupId>
            <artifactId>google-api-client-gson</artifactId>
            <version>2.0.0</version>
        </dependency>
  1. 配置类
// 基础配置
@Configuration
public class YoutubeConfig {
		// 这个是client_secrets.json的文件路径,这是自己写的demo,只要能加载就行
    private static String clientSecretsPath = "E:\\Java_source_code\\youtube-video\\youtube-admin\\src\\main\\resources\\config\\client_secrets.json";
		// 调用YouTubeApi所需权限列表,具体哪个url对应那个权限请翻阅YouTube官方文档
    private static List<String> roleList = Arrays.asList(
            "https://www.googleapis.com/auth/youtube",
            "https://www.googleapis.com/auth/youtube.channel-memberships.creator",
            "https://www.googleapis.com/auth/youtube.force-ssl",
            "https://www.googleapis.com/auth/youtube.readonly",
            "https://www.googleapis.com/auth/youtube.upload",
            "https://www.googleapis.com/auth/youtubepartner",
            "https://www.googleapis.com/auth/youtubepartner-channel-audit",
            "https://www.googleapis.com/auth/youtubepartner-content-owner-readonly"
    );

    @Bean
    public HttpTransport getHttpTransport() throws GeneralSecurityException, IOException {
        return GoogleNetHttpTransport.newTrustedTransport();
    }

    @Bean
    public JsonFactory getJsonFactory() {
        return GsonFactory.getDefaultInstance();
    }

    @Bean
    public GoogleClientSecrets getGoogleClientSecrets(JsonFactory jsonFactory) throws IOException {
        InputStream stream = new FileInputStream(new File(clientSecretsPath));
        return GoogleClientSecrets.load(jsonFactory, new InputStreamReader(stream));
    }


    @Bean
    public GoogleAuthorizationCodeFlow getGoogleAuthorizationCodeFlow(HttpTransport httpTransport,
                                                                      JsonFactory jsonFactory,
                                                                      GoogleClientSecrets clientSecrets) {
        return new GoogleAuthorizationCodeFlow.Builder(
                httpTransport, jsonFactory, clientSecrets,
                roleList)
                .build();
    }

    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

}

  1. 获取Google授权
@Controller
@RequestMapping(value = "/youtube")
public class YoutubeAuthController {

    @Value("${youtube.redirect-uri}")
    private String redirectUri;

    @Autowired
    private GoogleAuthorizationCodeFlow flow;

    @Autowired
    private GoogleClientSecrets clientSecrets;

    private static GoogleTokenResponse googleTokenResponse;


    private static String DOT = ",";

    public static ConcurrentHashMap<String,Credential> CREDENTIAL_MAP = new ConcurrentHashMap<>();


    /**
     * Google回调接口, 只有用户第一次授权时会返回refreshToken, 这里status作为requestId使用
     * @param code
     * @param scope
     * @param state
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/callback")
    @ResponseBody
    public String getYoutubeCallback(String code, String scope,String state) throws Exception {
        List<NameValuePair> parameters = new ArrayList<>();
        parameters.add(new BasicNameValuePair("code", code));
        parameters.add(new BasicNameValuePair("client_id", clientSecrets.getWeb().getClientId()));
        parameters.add(new BasicNameValuePair("client_secret", clientSecrets.getWeb().getClientSecret()));
        parameters.add(new BasicNameValuePair("grant_type", "authorization_code"));
        parameters.add(new BasicNameValuePair("redirect_uri",redirectUri));
        UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8.name());

        String url = "https://oauth2.googleapis.com/token";
        HttpPost request = new HttpPost();
        request.setEntity(encodedFormEntity);
        String response = HttpClientUtil.doPost(url, encodedFormEntity);
        System.out.println(response);
        TokenResponse tokenResponse = JSON.parseObject(response,TokenResponse.class);
        Credential credential = flow.createAndStoreCredential(tokenResponse, state);

        CREDENTIAL_MAP.put(state,credential);
        return "ok";
    }

    private String getRoleString(String roles) {
        if (roles.contains(DOT) && roles.endsWith(DOT)) {
            return roles.substring(0,roles.length() - 1);
        } else {
            return roles;
        }
    }

    /**
     * Google刷新令牌接口
     * @return
     */
    @RequestMapping(value = "/refreshToken")
    @ResponseBody
    public String refreshToken(String uid) throws Exception {
        Credential credential = CREDENTIAL_MAP.get(uid);
        List<NameValuePair> parameters = new ArrayList<>();
        parameters.add(new BasicNameValuePair("client_id", clientSecrets.getWeb().getClientId()));
        parameters.add(new BasicNameValuePair("client_secret", clientSecrets.getWeb().getClientSecret()));
        parameters.add(new BasicNameValuePair("grant_type", "refresh_token"));
        parameters.add(new BasicNameValuePair("refresh_token",credential.getRefreshToken()));
        UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8.name());

        String url = "https://oauth2.googleapis.com/token";
        HttpPost request = new HttpPost();
        request.setEntity(encodedFormEntity);
        return HttpClientUtil.doPost(url, encodedFormEntity);
    }

    /**
     * 获取用户授权url接口
     * @param uid
     * @return
     */
    @GetMapping(value = "/applyRole")
    @ResponseBody
    public String toApplyRole(String uid) {
        try {
            return flow.newAuthorizationUrl()
                    .setRedirectUri(redirectUri)
                    .setAccessType("offline")
                    // 这个值可以不设置,授权成功后Google会返回这个值给你
                    .setState(uid)
                    // 这个值是指定账号的,不用指定账号不用设置
                    .set("login_hint",uid)
                    .build();
        } catch (Exception e) {

            e.printStackTrace();
            return "the request happen a error in runtime";
        }
    }

    /**
     * Google撤销令牌接口
     * @return
     */
    @RequestMapping(value = "/revoke")
    @ResponseBody
    public String revokeToken(String refresh_token) throws Exception {
        Credential credential = CREDENTIAL_MAP.get(uid);

        String url1 = "https://oauth2.googleapis.com/revoke?token=" + refresh_token;
   //     String url2 = "https://oauth2.googleapis.com/revoke?token="+"1//0evHFaeshE0tACgYIARAAGA4SNwF-L9IrQoRaXWvYVLqgGk8jOl_KWlobz8q_uqk36vuwWD6MVHKoBHr-7n7e5aLNXP0AYYh5xQ0";
        return HttpClientUtil.doPost(url1, null);
    }
}

记住:同一个账号只能给一个应用授权一次,同一个账号再次授权会报错,这段代码先理解一下,了解一下我这是啥意思,再动手写自己的代码,不要盲目copy !!!

拿到访问令牌之后就能对YouYube的api进行访问了
下面试操作YouTube视频接口的代码

@Controller
@RequestMapping(value = "/api")
public class YouTubeApiController {

    @Autowired
    private JsonFactory jsonFactory;

    @Autowired
    private HttpTransport httpTransport;

    @Autowired
    private GoogleAuthorizationCodeFlow flow;

    private static final String APP_NAME = "web-app-youtube";





    @GetMapping(value = "/getChannel")
    @ResponseBody
    public ChannelListResponse getChannel(String uid) throws IOException {
         Credential credential = YoutubeAuthController.CREDENTIAL_MAP.get(uid);
        // 获取凭证
     /*   GoogleTokenResponse tokenResponse = JSON.parseObject("{\n" +
                "  \"access_token\": \"ya29.a0AX9GBdWDTl_WDHjAhMhqfHOv8Tee5o3Y8G-Un46rjLxVIXMBaUC8aUHzQWtwCzENq9EBPkN5WoXgiIgReOmBhEjIzJgZ3ZAbQt0em3m5NNFQe6LtL3Z0oj6UMHYHd0H4UJ2_N5Td1g3ggudW_539A09HtTV2aCgYKAdcSARASFQHUCsbCk4dDMR9R3-VivIgsglOayw0163\",\n" +
                "  \"expires_in\": 3599,\n" +
                "  \"refresh_token\": \"1//0eggCEbOSfmnnCgYIARAAGA4SNwF-L9IryVDE5t8GTDyOVAzPOPFc-TGJmiZOkUkzTVPLZuYMNOURZYA2fklO1_nhlSy3SOAsU4w\",\n" +
                "  \"scope\": \"https://www.googleapis.com/auth/youtubepartner https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtubepartner-channel-audit https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/youtubepartner-content-owner-readonly https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube.channel-memberships.creator\",\n" +
                "  \"token_type\": \"Bearer\"\n" +
                "}",GoogleTokenResponse.class);*/
        //Credential credential = flow.createAndStoreCredential(tokenResponse.transfer(),null);


        YouTube youtubeService = new YouTube.Builder(httpTransport, jsonFactory, credential).build();

        String respParam = "brandingSettings,id,status";
        YouTube.Channels.List request = youtubeService.channels().list(respParam);
        ChannelListResponse response = request
                .setMine(true)
                .execute();
        return response;
    }



    /**
     * Google上传视频接口
     * @return
     */
    @RequestMapping(value = "/uploadVideo")
    @ResponseBody
    public Video uploadVideo(String uid, MultipartFile file) throws Exception {

      /*  // 获取凭证
        GoogleTokenResponse tokenResponse = JSON.parseObject("{\n" +
                "  \"access_token\": \"ya29.a0AX9GBdWDTl_WDHjAhMhqfHOv8Tee5o3Y8G-Un46rjLxVIXMBaUC8aUHzQWtwCzENq9EBPkN5WoXgiIgReOmBhEjIzJgZ3ZAbQt0em3m5NNFQe6LtL3Z0oj6UMHYHd0H4UJ2_N5Td1g3ggudW_539A09HtTV2aCgYKAdcSARASFQHUCsbCk4dDMR9R3-VivIgsglOayw0163\",\n" +
                "  \"expires_in\": 3599,\n" +
                "  \"refresh_token\": \"1//0eggCEbOSfmnnCgYIARAAGA4SNwF-L9IryVDE5t8GTDyOVAzPOPFc-TGJmiZOkUkzTVPLZuYMNOURZYA2fklO1_nhlSy3SOAsU4w\",\n" +
                "  \"scope\": \"https://www.googleapis.com/auth/youtubepartner https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtubepartner-channel-audit https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/youtubepartner-content-owner-readonly https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube.channel-memberships.creator\",\n" +
                "  \"token_type\": \"Bearer\"\n" +
                "}",GoogleTokenResponse.class);

        Credential credential = flow.createAndStoreCredential(tokenResponse.transfer(),uid);*/

        Credential credential = YoutubeAuthController.CREDENTIAL_MAP.get(uid);
        YouTube youtubeService =  new YouTube.Builder(httpTransport, jsonFactory, credential).build();

        Video uploadedVideo = new Video();
        VideoStatus status = new VideoStatus();
        status.setPrivacyStatus("public");
        uploadedVideo.setStatus(status);
        VideoSnippet snippet = new VideoSnippet();
        snippet.setTitle(file.getOriginalFilename());
        uploadedVideo.setSnippet(snippet);
        InputStreamContent mediaContent =
                new InputStreamContent("application/octet-stream",
                        new BufferedInputStream(file.getInputStream()));

        YouTube.Videos.Insert videoInsert = youtubeService.videos()
                .insert("snippet,status,id,player", uploadedVideo, mediaContent);
        MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
        uploader.setDirectUploadEnabled(false);
        MediaHttpUploaderProgressListener progressListener = e -> {
            switch (e.getUploadState()) {
                case INITIATION_STARTED:
                    System.out.println("Initiation Started");
                    break;
                case INITIATION_COMPLETE:
                    System.out.println("Initiation Completed");
                    break;
                case MEDIA_IN_PROGRESS:
                    System.out.println("Upload in progress");
                    System.out.println("Upload percentage: " + e.getProgress());
                    break;
                case MEDIA_COMPLETE:
                    System.out.println("Upload Completed!");
                    break;
                case NOT_STARTED:
                    System.out.println("Upload Not Started!");
                    break;
            }
        };
        uploader.setProgressListener(progressListener);
        return videoInsert.execute();
    }

    /**
     * 获取视频列表
     * @param uid
     * @return
     * @throws IOException
     */
    @GetMapping(value = "/videoList")
    @ResponseBody
    public String getVideoList(String uid) throws IOException {
        // 获取凭证
    /*    TokenResponse tokenResponse = JSON.parseObject("{\n" +
                "  \"access_token\": \"ya29.a0AX9GBdWDTl_WDHjAhMhqfHOv8Tee5o3Y8G-Un46rjLxVIXMBaUC8aUHzQWtwCzENq9EBPkN5WoXgiIgReOmBhEjIzJgZ3ZAbQt0em3m5NNFQe6LtL3Z0oj6UMHYHd0H4UJ2_N5Td1g3ggudW_539A09HtTV2aCgYKAdcSARASFQHUCsbCk4dDMR9R3-VivIgsglOayw0163\",\n" +
                "  \"expires_in\": 3599,\n" +
                "  \"refresh_token\": \"1//0eggCEbOSfmnnCgYIARAAGA4SNwF-L9IryVDE5t8GTDyOVAzPOPFc-TGJmiZOkUkzTVPLZuYMNOURZYA2fklO1_nhlSy3SOAsU4w\",\n" +
                "  \"scope\": \"https://www.googleapis.com/auth/youtubepartner https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtubepartner-channel-audit https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/youtubepartner-content-owner-readonly https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube.channel-memberships.creator\",\n" +
                "  \"token_type\": \"Bearer\"\n" +
                "}",TokenResponse.class);
        Credential credential = flow.createAndStoreCredential(tokenResponse,uid);
        */
         Credential credential = YoutubeAuthController.CREDENTIAL_MAP.get(uid);
        YouTube youtubeService =  new YouTube.Builder(httpTransport, jsonFactory, credential).build();
        String part = "contentDetails,fileDetails,id,liveStreamingDetails,localizations,player,processingDetails,recordingDetails,snippet,statistics,status,suggestions,topicDetails";
        String videoId = "sYljcKUToF0";
        VideoListResponse listResp = youtubeService.videos().list(part).setId(videoId).execute();
        System.out.println(JSON.toJSONString(listResp));
        return JSON.toJSONString(listResp);
    }
}

请理解上面这段代码,以上便是访问YouTube的Api全部内容了,注意Google应用对接口的访问有配额限制,限制每日配额是1w , 其中 查询消耗配额为 1,新增修改删除消耗配额为50,上传视频消耗1600配额,超过配额接口将不可访问,需要申请提高配额,
另外上传的视频是有格式限制的:

YouTube支持的视频格式:文章来源地址https://www.toymoban.com/news/detail-669384.html

.MOV .MP4 .3GPP .MPEGPS
.MPEG-1 .MPG .WebM .FLV
.MPEG-2 .AVI .DNxHR .ProRes
.MPEG4 .WMV .CineForm .HEVC (h265)

到了这里,关于对接YouTube平台实现上传视频——Java实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python编程实现百度AI开放平台的接口对接方法,详解和实践指南

    Python编程实现百度AI开放平台的接口对接方法,详解和实践指南 引言 百度AI开放平台提供了丰富的人工智能接口,包括语音识别、图像识别、自然语言处理等功能。本文将通过Python编程,详解如何对接百度AI开放平台的接口,并提供实际代码示例。 准备工作 在开始之前,我们

    2024年02月13日
    浏览(43)
  • Java 调用 WebService 、java调用Soap请求、Java对接soap接口

    工作第一次遇到对接soap接口,觉得有必要记录一下,毕竟踩了不少坑,网上帖子很多但大都不全,也不可能完全满足自己的需求,于是就有了下面的代码: 除了只是借鉴, 注意事项: 1.http://ip:port/xxx/xxx/soap?wsdl有些soap接口,对面是不需要穿?wsdl对接时要问出清 2. httpPost.set

    2024年02月05日
    浏览(50)
  • java对接webservice接口的四种方式

    这两天一直在做外系统对接,对方的接口是webservice的形式,调用起来有些蛋疼,于是在这里记录一下我尝试过的调用WebService的三种方式。 方式一:以HttpURLConnection的方式调用 方式二:使用apache-cxf生成java类调用 下载apache-cxf并配置环境变量(参照JAVA环境变量配置),配置成

    2024年02月09日
    浏览(42)
  • 一文带你了解Java对接soap接口

    soap是一种简单的基于XML的协议:HTTP+RPC+XML A、Envelope(信封)元素,必选,可把此XML文档标识为一条SOAP消息。 B、Header(报头)元素,可选,包含头部信息(包含了使消息在到达最终目的地之前,能够被路由到一个或多个中间节点的信息)。 C、Body(主体)元素,必选,包含所有

    2024年02月08日
    浏览(39)
  • java对接第三方接口的三种方式

    在日常工作中,经常需要跟第三方系统对接,我们做为客户端,调用他们的接口进行业务处理,常用的几种调用方式有: 1.原生的Java.net.HttpURLConnection(jdk); 2.再次封装的HttpClient、CloseableHttpClient(Apache); 3.Spring提供的RestTemplate; 当然还有其他工具类进行封装的接口,比

    2024年04月28日
    浏览(60)
  • Java 微信小程序-发货信息录入接口 对接代码

    微信小程序-发货信息录入接口开发文档 POST https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=ACCESS_TOKEN 参见「查询物流公司编码列表」对接代码

    2024年02月03日
    浏览(69)
  • 基于java微信小程序视频分享平台系统设计与实现

    开发概要 小程序开发:微信开发者工具(MINA框架) 后台环境:JDK1.8 + Tomcat8 后台开发语言:Java 后台开发框架:springboot 后台模板引擎:Thymeleaf 后台开发工具:Idea2020 数据库:mysql8 数据库管理工具:navicat 其他开发语言:html + css +javascript

    2024年02月11日
    浏览(39)
  • SpringBoot3 + uniapp 对接 阿里云0SS 实现上传图片视频到 0SS 以及 0SS 里删除图片视频的操作(最新)

    UpLoadFile.vue deleteOssFile.js http.js FileUploadController.java AliOssUtil.java

    2024年04月14日
    浏览(47)
  • Java 亚马逊Amazon spapi对接开发,java Sdk,授权和接口访问步骤详细说明

    确认是否收到通过sp-api开发人员资料申请。   创建一个策略,我们建议您将 IAM 策略命名为 SellingPartnerAPI 。     开发商名称:任意字符 开发者id :accessKeyId 客户端相关信息,包含clientId和clientSecret。 1.8.1访问需要的参数和数据如图 参数 说明 样例 roleArn 角色Arn,在角色中

    2024年02月03日
    浏览(43)
  • Java电商平台 - API 接口设计之 token、timestamp、sign 具体架构与实现

    Token:访问令牌access token, 用于接口中, 用于标识接口调用者的身份、凭证,减少用户名和密码的传输次数。一般情况下客户端(接口调用方)需要先向服务器端申请一个接口调用的账号,服务器会给出一个appId和一个key, key用于参数签名使用,注意key保存到客户端,需要做一些安

    2024年02月07日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包