прямая трансляция на YouTube lifeCycleStatus застрял на «liveStarting»

Пытаюсь понять, что я делаю не так, когда транслирую в прямом эфире. У меня есть apk на моем телефоне Android для потоковой передачи на YouTube. У меня нет проблем с потоковой передачей в первый раз. Но если я остановлю его примерно на 2-3 минуты и снова буду транслировать, статус lifeCycleStatus бордкаста останется на «liveStarting», и мое видео не будет видно зрителям. Если я остановлюсь достаточно долго, перезапущу поток, статус станет «живым» примерно через 10 секунд. Я отключил enableMonitorStream, а также попробовал LiveBroadcasts.Transition, но он возвращает ошибку redundantTransition. Но lifeCycleStatus не стал бы «живым». Я также пытаюсь создать новую прямую трансляцию и прямую трансляцию и изменить статус на «прямой» вручную, но оба зависают на «liveStarting».

public class YoutubeService {

    private WeakReference<Context> context;
    private static final String PREF_ACCOUNT_NAME = "youtube_account_name";
    private static final String[] SCOPES = {YouTubeScopes.YOUTUBE};
    private GoogleAccountCredential mCredential;
    private YouTube mService;

    public YoutubeService(Context context) {
        this.context = new WeakReference<Context>(context);

        // create account credential
        mCredential = GoogleAccountCredential.usingOAuth2(
                context, Arrays.asList(SCOPES))
                .setBackOff(new ExponentialBackOff());
        mCredential.setSelectedAccountName("[email protected]");


        // create youtube builder
        HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        mService = new YouTube.Builder(
                transport, jsonFactory, mCredential)
                .setApplicationName("My App Name")
                .build();
    }


    // AsyncTask<Void, Void, Map<String, String>>
    private void getRtmpUrl() {

        try {

            // get livebroadcast list
            YouTube.LiveBroadcasts.List liveBroadcastRequest = mService.liveBroadcasts().list("id,snippet,contentDetails,status");
            liveBroadcastRequest.setBroadcastType("persistent");
            liveBroadcastRequest.setMine(true);
            LiveBroadcastListResponse liveBroadcastListResponse = liveBroadcastRequest.execute();

            List<LiveBroadcast> liveBroadcastList = liveBroadcastListResponse.getItems();
            if (liveBroadcastList != null && liveBroadcastList.size() > 0) {
                LiveBroadcast liveBroadcast = liveBroadcastList.get(0);
                String streamId = liveBroadcast.getContentDetails().getBoundStreamId();

                // get livestream list
                YouTube.LiveStreams.List livestreamRequest = mService.liveStreams().list("id,cdn");
                livestreamRequest.setId(streamId);
                LiveStreamListResponse liveStreamListResponse = livestreamRequest.execute();
                List<LiveStream> liveStreamList = liveStreamListResponse.getItems();

                if (liveStreamList != null && liveStreamList.size() > 0) {
                    LiveStream liveStream = liveStreamList.get(0);

                    String serverUrl = liveStream.getCdn().getIngestionInfo().getIngestionAddress();
                    String streamName = liveStream.getCdn().getIngestionInfo().getStreamName();
                    String rtmpUrl = serverUrl + "/" + streamName;
                    // use this rtmpUrl for streaming

                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    // call 30 seconds after press start streaming
    private void checkStatus() {
        try {
            // get livebroadcast list
            YouTube.LiveBroadcasts.List liveBroadcastRequest = mService.liveBroadcasts().list("id,snippet,contentDetails,status");
            liveBroadcastRequest.setBroadcastType("persistent");
            liveBroadcastRequest.setMine(true);
            LiveBroadcastListResponse liveBroadcastListResponse = liveBroadcastRequest.execute();

            List<LiveBroadcast> liveBroadcastList = liveBroadcastListResponse.getItems();
            if (liveBroadcastList != null && liveBroadcastList.size() > 0) {
                LiveBroadcast liveBroadcast = liveBroadcastList.get(0);


                // get lifeCycleStatus
                String lifeCycleStatus = liveBroadcast.getStatus().getLifeCycleStatus();
                String recordingStatus = liveBroadcast.getStatus().getRecordingStatus();
                if (lifeCycleStatus != null && lifeCycleStatus.equalsIgnoreCase("live") && recordingStatus != null && recordingStatus.equalsIgnoreCase("recording")) {
                    String videoId = liveBroadcast.getId();
                    // the url to watch is www.youtube.com/watch?v=videoId
                    // video is visible to audience


                } else {
                    // the status is stuck at 'liveStarting', video is not visible to audience
                    // "status":{"lifeCycleStatus":"liveStarting","privacyStatus":"public","recordingStatus":"recording"}


                    // check the status of livestream
                    String boundStreamId = liveBroadcast.getContentDetails().getBoundStreamId();
                    YouTube.LiveStreams.List livestreamRequest = mService.liveStreams().list("id,cdn,status");
                    livestreamRequest.setId(boundStreamId);

                    LiveStreamListResponse liveStreamListResponse = livestreamRequest.execute();
                    List<LiveStream> liveStreamList = liveStreamListResponse.getItems();

                    if (liveStreamList != null && liveStreamList.size() > 0) {
                        LiveStream liveStream = liveStreamList.get(0);


                        String streamStatus = liveStream.getStatus().getStreamStatus();
                        if (streamStatus.equalsIgnoreCase("active")) {

                            //                            Log.e(TAG,"need to transite to live, liveBroadcastId = " + liveBroadcast.getId());

                            YouTube.LiveBroadcasts.Transition liveBroadcastTransitionRequest =
                                    mService.liveBroadcasts().transition("live", liveBroadcast.getId(), "id,status");
                            LiveBroadcast liveBroadcastTransitionResponse = liveBroadcastTransitionRequest.execute();
                            // get error here
                            //                            error 403 Forbidden
                            //                            {
                            //                                "code" : 403,
                            //                                    "errors" : [ {
                            //                                "domain" : "youtube.liveBroadcast",
                            //                                        "message" : "Redundant transition",
                            //                                        "reason" : "redundantTransition"
                            //                            } ],
                            //                                "message" : "Redundant transition"
                            //                            }


                        }
                    }
                }


            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    // also try to create livebroadcast and live stream instead of the default one
    private void createLiveBroadcast() {
        try {

            // step 1 create live broadcast
            LiveBroadcastSnippet broadcastSnippet = new LiveBroadcastSnippet();
            broadcastSnippet.setTitle("Test live broadcast title");
            Date currentTime = Calendar.getInstance().getTime();
            broadcastSnippet.setScheduledStartTime(new DateTime(currentTime));

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

            // disable MonitorStreamInfo to change transition from ready to live
            // refrence https://stackoverflow.com/questions/35003786/cannot-make-transition-of-my-youtube-broadcast-to-live-using-youtube-api
            LiveBroadcastContentDetails contentDetails = new LiveBroadcastContentDetails();
            MonitorStreamInfo monitorStream = new MonitorStreamInfo();
            monitorStream.setEnableMonitorStream(false);
            contentDetails.setMonitorStream(monitorStream);

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

            YouTube.LiveBroadcasts.Insert liveBroadcastInsert =
                    mService.liveBroadcasts().insert("snippet,contentDetails,status", broadcast);
            LiveBroadcast returnedBroadcast = liveBroadcastInsert.execute();


            // step 2 create live stream
            String streamTitle = "Test Live Stream title";
            LiveStreamSnippet streamSnippet = new LiveStreamSnippet();
            streamSnippet.setTitle(streamTitle);

            CdnSettings cdnSettings = new CdnSettings();
            cdnSettings.setFormat("720p");
            cdnSettings.setIngestionType("rtmp");

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

            YouTube.LiveStreams.Insert liveStreamInsert =
                    mService.liveStreams().insert("snippet,cdn", stream);
            LiveStream returnedStream = liveStreamInsert.execute();
            if (returnedStream != null) {

                YouTube.LiveBroadcasts.Bind liveBroadcastBind =
                        mService.liveBroadcasts().bind(returnedBroadcast.getId(), "id,snippet,contentDetails,status");
                liveBroadcastBind.setStreamId(returnedStream.getId());
                returnedBroadcast = liveBroadcastBind.execute();

                String serverUrl = returnedStream.getCdn().getIngestionInfo().getIngestionAddress();
                String streamName = returnedStream.getCdn().getIngestionInfo().getStreamName();
                String rtmpUrl = serverUrl + "/" + streamName;
                // use this rtmpUrl for streaming

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

person Allan    schedule 03.04.2018    source источник
comment
На какую платформу и язык вы ориентируетесь? Можете ли вы предоставить больше кода для показа? Предоставленный вами код не компилируется, и мы не знаем, что это за язык.   -  person Mr. Young    schedule 04.04.2018
comment
Код обновлен. Я использую java на платформе Android. Спасибо!   -  person Allan    schedule 04.04.2018