No muchas veces, aunque sí alguna, nos toca trastear con alguna API de terceros para realizar alguna funcionalidad. Si tienes algo de suerte, esa API estará bien documentada, en el caso de YouTube: ¡ENHORABUENA!, la API está bien documentada y con buenos ejemplos, puedes verla aquí
¿Pero qué pasa cuando quieres salirte un poco de lo que te indican en la documentación? pues nada, a pegarse con Stackoverflow o búsquedas en foros, etc. En el caso que nos ocupa, siendo un proceso muy trillado ya, necesitamos un long life token para subir vídeos y consumir servicios sin tener que aceptar todo el tiempo los scopes de la app.
Usar long life token está indicado cuando necesitamos realizar peticiones en el servidor sin la necesidad de un usuario intermedio. Esta función requiere de una autenticación previa (realmente previamente necesitas más cosas que vemos en detalle más abajo) de modo que podamos obtener el token y el refresh token.
¡Vamos a la tarea!

Requisitos previos

Antes de nada, necesitamos una aplicación sobre la que realizamos las pruebas. En resumen, dado que no tienes más que visitar esta página te pongo un listado de lo que es necesario:

  1. Una cuenta de google si es que no dispones de una ya.
  2. Es necesario registrar tu aplicación para realizar las peticiones a la API.
  3. Debes seleccionar la API de datos de YouTube como uno de los servicios que usa tu aplicación. Puedes seleccionar todos los servicios que quieras que utilice tu aplicación.

Con esto ya es más que suficiente para empezar.

El siguiente paso consiste en descargarte el SDK, lo puedes obtener usando Composer:

"require": {::n::::t::"google/apiclient":"1.0.*@beta"::n::}

o clonarlo vía GitHub:

git clone -b v1-master https://github.com/google/google-api-php-client.git

Incluye la librería en tu aplicación

set_include_path(get_include_path() . PATH_SEPARATOR . '/path/to/google-api-php-client/src');

o cómo estés acostumbrado a incluirla... aquí al gusto del consumidor.

Una vez realizadas estas consideraciones podemos casi continuar. Falta una parte importante: obtener las claves para utilizar OAuth:

Ve a tu consola de aplicaciones de google. Clica en la pestaña de "Credenciales" de la izquierda.
En la página aparecerán ahora una serie de tabs con "Credenciales", "Pantalla de autorización de OAuth" y "Verificación de dominio". Si no te aparece nada en la pestaña de "Credenciales", debes obtener una credencial: clica en el botón de "Crear credenciales", puedes obtener una "Clave de API" (recomiendo tener una, así que créala sin miedo) y sobre todo, obtener un "ID de cliente de OAuth": clica en esta opción.

En la ventana que se muestra selecciona el tipo de aplicación "Web" (en principio la primera opción). Indica un nombre para la credencial. Si estás trabajando desde local, indica los orígenes de JavaScript como "localhost" y las "URIs de redireccionamiento autorizados" (impotantísimo) como "http://localhost/ruta_de_redireccionamiento_de_la_app". Puedes añadir tantas url de redireccionamiento como necesites.

Ahora te mostrará un ID de cliente y un Secreto de cliente, estos son los datos que usaremos para las peticiones más adelante, ¡tenlos a mano!

Importante

OAuth2 depende de SSL, con lo que es muy probable que debas tenerlo activado en tu máquina para que no te salte ningún error.

Hoja de ruta

Antes de ponernos a picar código, me gustaría dejar una hoja de ruta para obtener una visión global de lo que se quiere conseguir:

Como hemos visto más arriba, queremos que NO nos salte la verificación de la app cada vez que queramos realizar una petición, para ello es necesario que nos pida esos permisos una vez y, con lo que nos retorne, guardarlo para poder "refrescar" los tokens sin la necesidad de validar una y otra vez la petición (o cuando sea necesario).

Una vez tengamos esos permisos, podremos lanzar peticiones sin tener que aceptar las pantallas de verificación en cada petición o en cada tiempo de vida del token.

Luego, al menos tendremos dos métodos:

  1. gettoken(): Este método realiza la petición de credenciales (o actualización) de modo que podamos guardarlas para poder usarlas en nuestra app. En particular las credenciales tienen una duración de 1 hora (3600 segundos) pero no te preocupes, porque si está caducada, se podrá refrescar más adelante.
  2. upload(): Este método realiza la subida (a YouTube). No me interesa poner cómo subir el vídeo al servidor, pero se podría poner un formulario directamente, subir el vídeo al servidor y lanzar el upload... pero eso es otra historia, para lo que nos ocupa, supongamos que ya tenemos el vídeo disponible en el servidor. 

Con estos dos métodos tenemos dos URIs de redireccionamiento autorizadas: la primera para el gettoken() y la segunda para el upload() (claro, para las url asociadas a estas acciones). Supongamos que gettoken() tiene asociada la ruta http://localhost/miapp/youtube/gettoken/ y que upload() tiene asociada la ruta http://localhost/miapp/youtube/upload/ pues lo que hacemos es añadir estas dos url a la autorización dentro de nuestra consola de aplicacion de google, en la parte de las credenciales de OAuth (mira más arriba si quieres).

gettoken()

Lo primero es obtener los token y poder convertirlos en long life para luego usarlo sin la necesidad de tener que aceptar las verificaciones.

Para ello vamos a requerir del clientId y del clientSecret de las credenciales de OAuth.

...::n::session_start();::n::...::n::::n::function gettoken() {::n::::n::::t::$clientid       =  "[CLIENT ID AQUí]";::n::::t::$clientsecret   =  "[CLIENT SECRET AQUÍ]";::n::::t::$appname        =  "[NOMBRE DE APP]";::n::::t::$basePathToken  =  dirname( __FILE__ ) .  "/"; // ruta hasta el directorio para guardar el token como un fichero::n::::t::$redirect       =  filter_var( 'http://localhost/miapp/youtube/gettoken/',FILTER_SANITIZE_URL);::n::::n::::t::$client         =  new Google_Client();::n::::t::$client-::gt::setClientId( $clientid );::n::::t::$client-::gt::setClientSecret( $clientsecret );::n::::t::$client-::gt::setScopes( 'https://www.googleapis.com/auth/youtube','https://www.googleapis.com/auth/youtube.readonly','https://www.googleapis.com/auth/youtube.readonly','https://www.googleapis.com/auth/youtube.readonly','https://www.googleapis.com/auth/youtubepartner' );::n::::t::$client-::gt::setRedirectUri( $redirect );::n::::t::$client-::gt::setApplicationName( $appname );::n::::t::$client-::gt::setAccessType( 'offline' );::n::::t::$client-::gt::setApprovalPrompt( 'force' );::n::::n::::t::// el objeto encargado de realizar las llamadas a la api::n::::t::$youtube  =  new Google_Service_YouTube( $client );::n::::n::::t::if ( isset( $_GET[ 'code' ] ) ) :::n::::t::::t::if ( strval( $_SESSION[ 'state' ] ) !== strval( $_GET[ 'state' ] ) ) :::n::::t::::t::::t::die( 'El estado de la sesión no se corresponde.' );::n::::t::::t::endif;::n::::n::::t::::t::$client-::gt::authenticate( $_GET[ 'code' ] );::n::::t::::t::$_SESSION[ 'token' ]  =  $client-::gt::getAccessToken();::n::::t::endif;::n::::n::::t::if ( isset( $_SESSION[ 'token' ] ) ) :::n::::n::::t::::t::$client-::gt::setAccessToken( $_SESSION[ 'token' ] );::n::::t::::t:://En esta línea mostramos el token recibido, en tu programación no es necesario añadirla::n::::t::::t::echo "Access Token: " . json_encode( $_SESSION[ 'token' ] );::n::::t::::t::// salvamos el token.txt y redirige::n::::n::::t::::t::if ( !file_exists ( $basePathToken . 'token.txt' ) ) :::n::::n::::t::::t::::t::$handle  =  fopen( $basePathToken . 'token.txt',"w" );::n::::t::::t::::t::fwrite( $handle,json_encode( $_SESSION[ 'token' ] ) );::n::::t::::t::::t::fclose( $handle );::n::::n::::t::::t::else :::n::::n::::t::::t::::t::file_put_contents( $basePathToken . 'token.txt',json_encode( $_SESSION[ 'token' ] ) );::n::::n::::t::::t::endif;::n::::n::::t::::t:://redirigimos a la página aquí::n::::n::::t::endif;::n::::n::::t::// Se comprueba si se ha obtenido el access token.::n::::t::if ( !file_exists( $basePathToken . "/token.txt" ) ||  $client-::gt::getAccessToken() ) :::n::::n::::t::::t::$state  =  mt_rand();::n::::t::::t::$client-::gt::setState( $state );::n::::t::::t::$_SESSION[ 'state' ]  =  $state;::n::::n::::t::::t::$authUrl  =  $client-::gt::createAuthUrl();::n::::t::::t::echo '

Autorización requerida

::n::::t::::t::

Se necesita una autorización de acceso antes de proceder.

';::n::::n::::t::endif;::n::}

Paso a paso, dado que vamos a trabajar con sesiones, es preciso iniciar la sesión con un session_start(); antes de nada. Si no no podríamos trabajar con sesiones. Por otro la función gettoken() se llama suponiendo un patrón MVC, en mi caso, es la acción de un controlador, pero puede ocurrir que no tengas un FW o una programación con este patrón y por lo tanto, lo puedes usar sacando el código fuera de la función (y sin los puntos suspensivos, claro...).

$redirect le indica la url de retorno que debe coincidir con las rutas que tengas activas en el panel de la app dentro de la consola de desarrolladores de google.

Luego, siguiendo el código no le veo mucha complicación, la parte de $client = new Google_Client(); crea el cliente para las peticiones a la plataforma, se le pasan las credenciales con setClientId() y setClientSecret(), los permisos con setScopes(), la redirección con setRedirectUri() y la parte más importante para lo que nos ocupa que es setAccessType( 'offline' ) y setApprovalPrompt( 'force' ); esto nos permite realizar las consultas sin la interacción del usuario (casi) teniendo los tokens de consulta y de refresco, pero ciertamente, un usuario, en un punto, debe permitir el acceso en un punto dado.

new Google_Service_YouTube( $client ); es el objeto que permite realizar las peticiones a YouTube, en este caso lo he dejado como muestra de cómo crearlo, aunque no lo usamos en ninguna parte del código. Lo que hacemos es jugar con el objeto $cliente para comprobar si ha conseguido obtener los tokens. En el caso de no conseguirlo, el usuario deberá acceder a la ruta de autenticación ($client->createAuthUrl()) y de forma implícita aceptar los permisos para la aplicación. En este punto, salimos de nuestra aplicación, aceptamos o denegamos y retornamos a través de la url de retorno, en la que se obtienen como parámetros "GET" el "code" y el "state". Con el "code", a través del cliente con $client->authenticate( $_GET[ 'code' ] );

El comentario será validado antes de mostrarse.