android - 通过 android 在 youtube 上直播时处于非 Activity 状态

标签 android youtube-api android-youtube-api youtube-data-api

我可以通过 Youtube API 创建 Activity 。 Activity 正在我的 Youtube 页面“Activity 选项卡”(即将推出的类别)中显示。 但是当我开始流式传输时,它会返回错误 403(流处于非 Activity 状态)。我想在每次直播时创建一个新的广播事件。 任何帮助将不胜感激。这是我的代码....

这是在 AsyncTask 中:

YouTube youtube = new YouTube.Builder(transport, jsonFactory,
        credential).setApplicationName(APP_NAME).build();

YouTubeApi.createLiveEvent(youtube, "event description", "event name");    

在方法 YoutubeApi.createLiveEvent(...) 中:

public static void createLiveEvent(YouTube youtube, String description,
    String name) {

    try {

        LiveBroadcastSnippet broadcastSnippet = new LiveBroadcastSnippet();
        broadcastSnippet.setTitle(name);
        broadcastSnippet.setScheduledStartTime(new DateTime(new Date()));

        LiveBroadcastContentDetails contentDetails = new LiveBroadcastContentDetails();
        MonitorStreamInfo monitorStream = new MonitorStreamInfo();
        monitorStream.setEnableMonitorStream(false);
        contentDetails.setMonitorStream(monitorStream);

        // Create LiveBroadcastStatus with privacy status.
        LiveBroadcastStatus status = new LiveBroadcastStatus();
        status.setPrivacyStatus("public");


        LiveBroadcast broadcast = new LiveBroadcast();
        broadcast.setKind("youtube#liveBroadcast");
        broadcast.setSnippet(broadcastSnippet);
        broadcast.setStatus(status);
        broadcast.setContentDetails(contentDetails);

        // Create the insert request
        YouTube.LiveBroadcasts.Insert liveBroadcastInsert = youtube
            .liveBroadcasts().insert("snippet,status,contentDetails",
                broadcast);

        // Request is executed and inserted broadcast is returned
        LiveBroadcast returnedBroadcast = liveBroadcastInsert.execute();

        // Create a snippet with title.
        LiveStreamSnippet streamSnippet = new LiveStreamSnippet();
        streamSnippet.setTitle(name);

        // Create content distribution network with format and ingestion
        // type.
        CdnSettings cdn = new CdnSettings();
        cdn.setFormat("240p");
        cdn.setIngestionType("rtmp");

        LiveStream stream = new LiveStream();
        stream.setKind("youtube#liveStream");
        stream.setSnippet(streamSnippet);
        stream.setCdn(cdn);

        // Create the insert request
        YouTube.LiveStreams.Insert liveStreamInsert = youtube.liveStreams()
            .insert("snippet,cdn", stream);

        // Request is executed and inserted stream is returned
        LiveStream returnedStream = liveStreamInsert.execute();

        // Create the bind request
        YouTube.LiveBroadcasts.Bind liveBroadcastBind = youtube
            .liveBroadcasts().bind(returnedBroadcast.getId(),
                "id,contentDetails");

        // Set stream id to bind
        liveBroadcastBind.setStreamId(returnedStream.getId());

        // Request is executed and bound broadcast is returned
        liveBroadcastBind.execute();

    } catch (GoogleJsonResponseException e) {
        System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : " + e.getDetails().getMessage());
        e.printStackTrace();

    } catch (IOException e) {
        System.err.println("IOException: " + e.getMessage());
        e.printStackTrace();
    } catch (Throwable t) {
        System.err.println("Throwable: " + t.getStackTrace());
        t.printStackTrace();
    }
}

这是我启动事件流的代码:

public static void startEvent(YouTube youtube, String broadcastId) // broadcast id is same(checked)
        throws IOException {

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        Log.e(APP_NAME, "", e);
    }

    YouTube.LiveStreams.List liveBroadcastRequest = youtube
            .liveStreams().list("id,snippet,status");
    // liveBroadcastRequest.setMine(true);
    liveBroadcastRequest.setId(broadcastId);  //  setBroadcastStatus("upcoming");



    // List request is executed and list of broadcasts are returned
    LiveStreamListResponse returnedListResponse = liveBroadcastRequest.execute();
    List<LiveStream> returnedList = returnedListResponse.getItems();


    Transition transitionRequest = youtube.liveBroadcasts().transition(
            "live", broadcastId, "status");
    transitionRequest.execute();
}

我收到的异常日志:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code": 403,
  "errors": [
    {
      "domain": "youtube.liveBroadcast",
      "message": "Stream is inactive",
      "reason": "errorStreamInactive",
      "extendedHelp": "https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/transition"
    }
  ],
  "message": "Stream is inactive"
}
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at net.ossrs.yasea.demo.utils.YouTubeApi.startEvent(YouTubeApi.java:236)
at net.ossrs.yasea.demo.rtmp.YoutubeRTMPUrl$StartEventTask.doInBackground(YoutubeRTMPUrl.java:160)
at net.ossrs.yasea.demo.rtmp.YoutubeRTMPUrl$StartEventTask.doInBackground(YoutubeRTMPUrl.java:144)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818

最佳答案

几天前我遇到了类似的问题...这就是我所做的...

要记住的要点:a) 您可能会在 API 中收到与 youtube Activity 门户不同的 RTMP url。

b) 无论您是否能够“上线”,您都可能在将广播转换为“直播”状态时收到 403 错误。

现在出现错误 403(流处于非 Activity 状态):

确保在调用“广播过渡”之前将帧/数据发送到 youtube。 现在在线程暂停几秒的差异线程上调用“Broadcast.transition”(将数据发送到 youtube 可能需要一些时间)。

例如:

public static void startEvent(final YouTube youtube, final String broadcastId) 抛出 IOException {

    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        Log.e(APP_NAME, "", e);
    }

    Transition transitionRequest = youtube.liveBroadcasts().transition(
            "live", broadcastId, "status");
    transitionRequest.execute();
}

希望对您有所帮助....

关于android - 通过 android 在 youtube 上直播时处于非 Activity 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42371396/

相关文章:

youtube - 从 Youtube API 获取记录时 "Using and not using API key"有什么区别

javascript - Youtube API,不允许除声音控制之外的控制?

android - 向 View 中添加多个YouTube fragment 会导致正在加载同一视频

android - Activity fragment

java - Leaderboard_id 无法解析或不是字段错误

javascript - 移动原生键盘自动建议阻止加载 javascript 自动完成小部件

android - ListView 在 Android 中不可见

ios - 在不要求用户登录的情况下检索 youtube 播放列表

java - view = inflater.inflate(R.layout.video_list_item,parent,false);导致强制关闭错误

android - YouTube Android Player API是否会使用YouTube应用程序中的帐户?