0

When trying to create an event on YouTube using YouTube Data API I get following error only in case of very few users:

Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet%2Cstatus: (403) The user is not enabled for live streaming.' in E:\Rupesh\Websites\abtv\abstream\Google\Http\REST.php on line 110

Please also note following :

  1. The user id is of the form xyz@gmail.com only. I know for fact, this code does not work for user id of the form xyz@@pages.plusgoogle.com.

  2. User is authenticated using Google's OAuth 2 prior to calling this function.

  3. User has allowed access to Web Application using @gmail.com id.

Following is class I have put together:

set_include_path(get_include_path() . PATH_SEPARATOR . '/home/aprilbr3/public_html/google-api-php-client/src');

require_once 'Google/autoload.php';
require_once 'Google/Client.php';
require_once 'Google/Service/Oauth2.php';

require_once 'class.miscellaneous_functions.php';


class GoogleClient
{
    public static $cdn_formats = array(
        "Poor" => "240p", "Ok" => "360p", "Good" => "480p", "Better" => "720p", "Best" => "1080p");
    public static $privacy_statuses = array(
        "public" => "public", "unlisted" => "unlisted", "private" => "private");

    private static $OAUTH2_CLIENT_ID = 'CLIENT_ID_HERE';
    private static $OAUTH2_CLIENT_SECRET = 'CLIENT_SECRET_HERE';
    private static $privacy_status = "public"; // $privacy_statuses["public"];
    //private static $cdn_format = $cdn_formats["Ok"];
    private static $cdn_injestion_type = "rtmp";

    var $client;
    var $plus;
    var $redirect_url;
    var $user_info;

    function __construct()
    {
        $this->client = new Google_Client();
        $this->client->setClientId(GoogleClient::$OAUTH2_CLIENT_ID);
        $this->client->setClientSecret(GoogleClient::$OAUTH2_CLIENT_SECRET);
        $redirect_url = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
            FILTER_SANITIZE_URL);
        $this->client->setRedirectUri($redirect_url);

        $this->client->setScopes(array(
            'https://www.googleapis.com/auth/userinfo.email',
            'https://www.googleapis.com/auth/userinfo.profile',
            'https://www.googleapis.com/auth/youtube'));
        $this->plus = new Google_Service_Oauth2($this->client);
    } // __construct()

    function OAuth2()
    {
        if (!isset($_SESSION))
            session_start();

        if (isset($_REQUEST['logout'])) {
            unset($_SESSION['access_token']);
        }

        if (isset($_GET['code'])) {
            try {
                $this->client->authenticate($_GET['code']);
            } catch (Google_Auth_Exception $e) {
                MiscellaneousFunctions::DestroySessionAndRedirectTo($this->redirect_url);
            }
            $_SESSION['access_token'] = $this->client->getAccessToken();
            header('Location:' . $this->redirect_url);
        }

        if (isset($_SESSION['access_token'])) {
            $this->client->setAccessToken($_SESSION['access_token']);
        }

        $error = false;
        if (!$this->client->getAccessToken()) {
            $error = true;
        }

        if (!$error) {
            try {
                $user_info = $this->plus->userinfo->get();
                return array('result' => true, 'user_info' => $user_info);
            } catch (Google_Service_Exception $e) {
                MiscellaneousFunctions::DestroySessionAndRedirectTo($this->redirect_url);
                //exit();

            } catch (Google_Exception $e) {
                MiscellaneousFunctions::DestroySessionAndRedirectTo($this->redirect_url);
                //exit();
            }
        }
        return array('result' => false, 'auth_url' => $this->client->createAuthUrl());
        //MiscellaneousFunctions::DestroySessionAndRedirectTo($this->client->createAuthUrl());
        //exit();

    } // OAuth2

    function CreateEvent($broadcast_title, $broadcast_description, $cdn_format,
                         $start_date_time, $end_date_time)
    {
        //echo( "Step 1" . "\n<br><br><br>");

        $stream_title = "Stream for " . $broadcast_title;
        $youtube = new Google_Service_YouTube($this->client);

        try {
            // Create an object for the liveBroadcast resource's snippet. Specify values
            // for the snippet's title, scheduled start time, and scheduled end time.
            $broadcastSnippet = new Google_Service_YouTube_LiveBroadcastSnippet();
            $broadcastSnippet->setTitle($broadcast_title);

            //echo( "Step 2" . "\n<br><br><br>");
            //echo( "Start Time : " . MiscellaneousFunctions::GetDateTimeStringForYoutube($start_date_time) . "\n</br>");
            //echo( "End Time : " . MiscellaneousFunctions::GetDateTimeStringForYoutube($end_date_time) . "\n</br>");
            //exit;

            $broadcastSnippet->setScheduledStartTime(
                MiscellaneousFunctions::GetDateTimeStringForYoutube($start_date_time));
            $broadcastSnippet->setScheduledEndTime(
                MiscellaneousFunctions::GetDateTimeStringForYoutube($end_date_time));
            $broadcastSnippet->setDescription($broadcast_description);

            //echo( "Step 3" . "\n<br><br><br>");

            // Create an object for the liveBroadcast resource's status, and set the
            // broadcast's status to "private".
            $status = new Google_Service_YouTube_LiveBroadcastStatus();
            $status->setPrivacyStatus(GoogleClient::$privacy_status);

            //echo( "Step 4" . "\n<br><br><br>");

            // Create the API request that inserts the liveBroadcast resource.
            $broadcastInsert = new Google_Service_YouTube_LiveBroadcast();
            $broadcastInsert->setSnippet($broadcastSnippet);
            $broadcastInsert->setStatus($status);
            $broadcastInsert->setKind('youtube#liveBroadcast');

            //echo( "Step 5" . "\n<br><br><br>");
            //echo( json_encode( $youtube ) . "\n<br><br><br>");

            // Execute the request and return an object that contains information
            // about the new broadcast.
            $broadcastsResponse = $youtube->liveBroadcasts->insert('snippet,status',
                $broadcastInsert, array());

            //echo( "Step 6" . "\n<br><br><br>");

            // Create an object for the liveStream resource's snippet. Specify a value
            // for the snippet's title.
            $streamSnippet = new Google_Service_YouTube_LiveStreamSnippet();
            $streamSnippet->setTitle($stream_title);

//            echo( "Step 7" . "\n<br><br><br>");

            // Create an object for content distribution network details for the live
            // stream and specify the stream's format and ingestion type.
            $cdn = new Google_Service_YouTube_CdnSettings();
            $cdn->setFormat($cdn_format);
            $cdn->setIngestionType(GoogleClient::$cdn_injestion_type);

//            echo( "Step 8" . "\n<br><br><br>");

            // Create the API request that inserts the liveStream resource.
            $streamInsert = new Google_Service_YouTube_LiveStream();
            $streamInsert->setSnippet($streamSnippet);
            $streamInsert->setCdn($cdn);
            $streamInsert->setKind('youtube#liveStream');

//            echo( "Step 9" . "\n<br><br><br>");

            // Execute the request and return an object that contains information
            // about the new stream.
            $streamsResponse = $youtube->liveStreams->insert('snippet,cdn', $streamInsert, array());

            // Bind the broadcast to the live stream.
            $bindBroadcastResponse = $youtube->liveBroadcasts->bind(
                $broadcastsResponse['id'], 'id,contentDetails',
                array('streamId' => $streamsResponse['id'],));

//            echo( "Step 10" . "\n<br><br><br>");

            return array('result' => true,
                'broadcasts_response' => $broadcastsResponse,
                //'broadcasts_response_id' => $broadcastsResponse['id'],
                //'broadcasts_response_snippet' => $broadcastsResponse['snippet'],
                'streams_response' => $streamsResponse
                //'streams_response_id' => $streamsResponse['id'],
                //'streams_response_snippet' => $streamsResponse['snippet'],
                //'streams_response_cdn' => $streamsResponse['cdn'],
                //'streams_response_cdn_ingestionInfo' => $streamsResponse['cdn']['ingestionInfo']
            );
        } catch (Google_Service_Exception $e) {
            //MiscellaneousFunctions::DestroySessionAndRedirectTo($this->redirect_url);
            $reason = json_encode($e->getMessage(), JSON_PRETTY_PRINT);
            //echo( "Google_Service_Exception:" . json_encode( $e ) . "\n<br><br><br>");
//            return array('result' => false, 'reason' => $reason);

        } catch (Google_Exception $e) {
            //MiscellaneousFunctions::DestroySessionAndRedirectTo($this->redirect_url);
            $reason = json_encode($e->getMessage(), JSON_PRETTY_PRINT);
            //echo( "Google_Exception:" . json_encode( $e ) . "\n<br><br><br>");
            //return array('result' => false, 'reason' => $reason);
        }
        return array('result' => false, 'reason' => $reason);
    }

    function GetEvent( $broadcast_id )
    {
        $youtube = new Google_Service_YouTube($this->client);
        try {
            // Execute an API request that lists broadcasts owned by the user who
            // authorized the request.
            $broadcastsResponse = $youtube->liveBroadcasts->listLiveBroadcasts(
                'id,snippet,contentDetails,status',
                array( 'id' => $broadcast_id ));

            $broadcastItem = $broadcastsResponse['items'][0];
            $streamId = $broadcastItem['contentDetails']['boundStreamId'];
            $streamsResponse = $youtube->liveStreams->listLiveStreams(
                'id,snippet,cdn,status',
                array( 'id' => $streamId ));
            $streamItem = $streamsResponse['items'][0];
            return array('result' => true,
                'broadcasts_response' => $broadcastItem,
                'streams_response' => $streamItem
            );
        } catch (Google_Service_Exception $e) {
            $reason = json_encode($e->getMessage(), JSON_PRETTY_PRINT);
        } catch (Google_Exception $e) {
            $reason = json_encode($e->getMessage(), JSON_PRETTY_PRINT);
        }
        return array('result' => false, 'reason' => $reason);
    }
} // class GoogleClient

Thank you.

Rupesh

P.S: Sorry, I forgot to mention that all the users of the system have enabled live streaming in their respective youtube accounts. That's what puzzles me!

Rupesh Bhurke
  • 162
  • 1
  • 8

0 Answers0