首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过android在youtube上运行的非活动流

通过android在youtube上运行的非活动流
EN

Stack Overflow用户
提问于 2017-02-21 15:25:48
回答 2查看 1.8K关注 0票数 1

我能够通过Youtube api创建一个事件。事件正在我的Youtube页面"events选项卡“(即将到来的类别)中显示。但是,当我开始流时,它返回错误403 (流是不活动的),.I希望每次我要运行时都创建一个新的广播事件。任何帮助都将不胜感激。这是我的密码..。

这是在AsyncTask中的:

代码语言:javascript
运行
复制
YouTube youtube = new YouTube.Builder(transport, jsonFactory,
        credential).setApplicationName(APP_NAME).build();

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

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

代码语言:javascript
运行
复制
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();
    }
}

下面是启动事件流的代码:

代码语言:javascript
运行
复制
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();
}

我收到的异常日志:

代码语言:javascript
运行
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-23 18:59:40

几天前我也面临着类似的问题back...here是我做的.

请记住:( a)您可能会收到API中的diff RTMP url,而不是youtube事件门户。

( b)无论您是否能够“直播”,您在调用广播到状态"Live“的转换时可能会收到403个错误。

现在发出错误403(流是非活动的):

在调用“广播过渡”之前,一定要将帧/数据发送到youtube。现在用线程暂停数秒钟在一个不同的线程上调用"Broadcast.transition“(向youtube发送数据可能需要时间)。

例:

公共静态空startEvent( YouTube youtube,最终字符串broadcastId)抛出IOException {

代码语言:javascript
运行
复制
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        Log.e(APP_NAME, "", e);
    }

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

希望这能帮上忙..。

票数 2
EN

Stack Overflow用户

发布于 2017-02-21 23:57:06

您需要等待流状态切换到active。因此,您必须存储您的流ID和广播ID,等待此状态。

可以使用TimerTaskScheduledExecutorService完成检查:

代码语言:javascript
运行
复制
mScheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();

// check every 2 seconds the stream status
mScheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        try {
            if (mStreamId != null) {
                checkStreamStatus();
            }
        } catch (IOException e) {
            Log.e(TAG, null, e);
        }
    }
}, 0, 2, TimeUnit.SECONDS);

checkStreamStatus方法检查流状态,如果需要也可以检查流状态(health "GOOD"):

代码语言:javascript
运行
复制
public void checkStreamStatus() throws IOException {

    YouTube.LiveStreams.List livestreamRequest = youtube.liveStreams().list("status");
    livestreamRequest.setId(mStreamId);

    LiveStreamListResponse returnedListResponse = livestreamRequest.execute();
    List < LiveStream > returnedList = returnedListResponse.getItems();

    if (returnedList.size() == 1) {

        LiveStream stream = returnedList.get(0);

        Log.v(TAG, "the current stream status is : " + stream.getStatus().getStreamStatus());

        if (stream.getStatus().getStreamStatus().equals("active")) {
            Log.v(TAG, "start broadcasting now");
            startEvent();
            mScheduleTaskExecutor.shutdownNow();
        }
    }
}

下面是一个完整的例子:

代码语言:javascript
运行
复制
public class YoutubeTask extends AsyncTask < Void, Void, String > {

    private final static String TAG = YoutubeTask.class.getSimpleName();

    private ScheduledExecutorService mScheduleTaskExecutor;

    private String mStreamId;
    private String mBroadcastId;

    private static YouTube youtube;

    @Override
    protected String doInBackground(Void...params) {

        mScheduleTaskExecutor = Executors.newSingleThreadScheduledExecutor();

        // Authorize the request.
        Credential credential = new GoogleCredential().setAccessToken("...");

        // This object is used to make YouTube Data API requests.
        youtube = new YouTube.Builder(new NetHttpTransport(), new JacksonFactory(), credential)
            .setApplicationName("youtube-cmdline-createbroadcast-sample").build();

        createLiveEvent(youtube, "event name");

        // check every 2 seconds the stream status
        mScheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    if (mStreamId != null) {
                        checkStreamStatus();
                    }
                } catch (IOException e) {
                    Log.e(TAG, null, e);
                }
            }
        }, 0, 2, TimeUnit.SECONDS);

        return null;
    }

    public void createLiveEvent(YouTube youtube, 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);

            LiveBroadcastStatus status = new LiveBroadcastStatus();
            status.setPrivacyStatus("public");

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

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

            LiveBroadcast returnedBroadcast = liveBroadcastInsert.execute();

            LiveStreamSnippet streamSnippet = new LiveStreamSnippet();
            streamSnippet.setTitle(name);

            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();

            // store stream Id & broadcast Id
            mStreamId = returnedStream.getId();
            mBroadcastId = returnedBroadcast.getId();

        } catch (GoogleJsonResponseException e) {
            Log.e(TAG, null, e);
        } catch (IOException e) {
            Log.e(TAG, null, e);
        } catch (Throwable t) {
            Log.e(TAG, null, t);
        }
    }

    public void checkStreamStatus() throws IOException {

        YouTube.LiveStreams.List livestreamRequest = youtube.liveStreams().list("status");
        livestreamRequest.setId(mStreamId);

        LiveStreamListResponse returnedListResponse = livestreamRequest.execute();
        List < LiveStream > returnedList = returnedListResponse.getItems();

        if (returnedList.size() == 1) {

            LiveStream stream = returnedList.get(0);

            Log.v(TAG, "the current stream status is : " + stream.getStatus().getStreamStatus());

            if (stream.getStatus().getStreamStatus().equals("active")) {
                Log.v(TAG, "start broadcasting now");
                startEvent();
                mScheduleTaskExecutor.shutdownNow();
            }
        }
    }

    public void startEvent() throws IOException {
        YouTube.LiveBroadcasts.Transition transitionRequest = youtube.liveBroadcasts().transition(
            "live", mBroadcastId, "status");
        transitionRequest.execute();
    }
}

使用new YoutubeTask().execute();启动此示例

您可以使用从奥奥斯游乐场获取的带有作用域https://www.googleapis.com/auth/youtube的访问令牌直接测试这一点。此外,为了测试流,我建议使用Android应用程序RTMP摄像机将相机流测试到Youtube,在那里您可以直接将stream XXXX-XXXX-XXXX-XXXX

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42371396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档