nodejs对接YouTube Live api

Auth by oAuth2

require: client_id, client_secret

  const env = {
    google: {
      clientId: '',
      clientSecret: '',
      redirect: '', // redirect url. api server地址,带上特定path,完成认证后会回调此地址
    },
  };
  const { google } = npm.googleapis
  const OAuth2 = google.auth.OAuth2;
  const oAuth2Client = new google.auth.OAuth2(
    env.google.clientId, env.google.clientSecret, env.google.redirect
  );
  const SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl'];
  const authUrl = oAuth2Client.generateAuthUrl({
     access_type: 'offline',
     scope: SCOPES
  });
  // send the authUrl by email or any other
  return authUrl;

Auth Callback

拿到authUrl后,引导用户访问authUrl,然后跳转到回调地址redirect,得到code。比如回调地址:

/auth/google

在认证完成后,会发起请求:

/auth/google?code=

在请求的处理方法中,根据code获取token。

  const env = {
    google: {
      clientId: '',
      clientSecret: '',
      redirect: '', // redirect url. api server地址,带上特定path,完成认证后会回调此地址
    },
  };
  const { google } = npm.googleapis
  const oAuth2Client = new google.auth.OAuth2(
    env.google.clientId, env.google.clientSecret, env.google.redirect
  )
  const tokenRes = await oAuth2Client.getToken(CODE); // CODE is from query
  oAuth2Client.setCredentials(tokenRes.tokens);

至此得到oAuth2Client

创建Broadcast

  const { google } = npm.googleapis;
  const authClient = await getOAuth2Client(); // 前面得到的 oAuth2Client
  const youtube = google.youtube('v3');
  google.options({auth: authClient})
  const res = await youtube.liveBroadcasts.insert({
    part: [
      "id,snippet,contentDetails,status"
    ],
    resource: {
      contentDetails: {
        enableEmbed: true,
        monitorStream: {
          enableMonitorStream: false // 如果这里不设置,默认为true,则必须先test才能live,否则一直提示 invalidTransition
        }
      },
      snippet: {
        scheduledStartTime: 'start_time',
        title,
        description,
      },
      status: {
        privacyStatus: "unlisted"
      }
    }
  });
  const { id: broadcastId } = res.data;
  return broadcastId;

创建Stream

  const { google } = npm.googleapis;
  const authClient = await getOAuth2Client(); // 前面得到的 oAuth2Client
  const youtube = google.youtube('v3');
  google.options({auth: authClient})
  const res = await youtube.liveStreams.insert(
    {
      "part": [
        "id,snippet,cdn,contentDetails,status"
      ],
      "resource": {
        "cdn": {
          "ingestionType": "rtmp",
          "resolution": "1440p",
          "frameRate": "60fps"
        },
        "snippet": {
          "title": title
        }
      }
    }
  );
  const { id: streamId, cdn } = res.data;
  const { streamName: streamKey, ingestionAddress: streamUrl} = cdn.ingestionInfo;
  return {
    streamId, // 流唯一id
    streamKey, // 推流的key
    streamUrl, // 推流地址
  };

绑定Broadcast & Stream

  const { google } = npm.googleapis;
  const authClient = await getOAuth2Client(); // 前面得到的 oAuth2Client
  const youtube = google.youtube('v3');
  google.options({auth: authClient})
  await youtube.liveBroadcasts.bind(
    {
      "id": broadcastId,
      "part": [
        "snippet,contentDetails,status"
      ],
      "streamId": streamId
    }
  );

测试Broadcast

  const { google } = npm.googleapis;
  const authClient = await getOAuth2Client(); // 前面得到的 oAuth2Client
  const youtube = google.youtube('v3');
  google.options({auth: authClient})
  await youtube.liveBroadcasts.transition({
      "broadcastStatus": "testing",
      "id": broadcastId,
      "part": [
        "snippet"
      ]
  })

如果前面创建Broadcast时,contentDetails.monitorStream.enableMonitorStream = true,那么必须先调用这个测试方法,把broadcastStatus设置为testing,才能做后续操作。

开始Broadcast

  const { google } = npm.googleapis;
  const authClient = await getOAuth2Client(); // 前面得到的 oAuth2Client
  const youtube = google.youtube('v3');
  google.options({auth: authClient})
  await youtube.liveBroadcasts.transition({
      "broadcastStatus": "live",
      "id": broadcastId,
      "part": [
        "snippet,status"
      ]
  })

如果报错 invalidTransition,403,forbidden ,有可能是contentDetails.monitorStream.enableMonitorStream = true 并且没有test。

在开始之前,必须先推流,推流后才能正常开始。

No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
Previous