PHP: YouTube v3 API Captions Upload with Sync Flag

За последние пару недель мои коллеги и я работали над попытками получить подписки на наших клиентов видео YouTube через API v3. Примерно через неделю мы наконец получили возможность загружать субтитры, но YouTube предоставил нам это сообщение в интерфейсе пользователя . Трек-контент не обрабатывается и не отображает заголовок, который мы загружаем, Однако мы можем загрузить исходный формат, который был загружен; поэтому мы знаем, что файл был загружен успешно.

Нам также удалось получить флаг синхронизации для работы, который говорит YouTube, что он просматривает транскрипцию и устанавливает тайминги для видео, но на самом деле это не работает. Он возвращается, сообщая нам, что он синхронизируется, но когда мы переходим к пользовательскому интерфейсу для видео, он просто показывает название трека и дает нам сообщение "Содержание трека не обрабатывается".. Мы потратили все часы, которые у нас были, и теперь мы работаем над своим временем, чтобы решить эту проблему, но все равно не повезло.

Кто-нибудь сталкивался с этой проблемой раньше? Если да, то что вы могли сделать, чтобы заставить это работать?

Я опубликую фрагмент кода ниже, который показывает часть загрузки нашего script.

# Insert a video caption.
# Create a caption snippet with video id, language, name and draft status.
$captionSnippet = new Google_Service_YouTube_CaptionSnippet();
$captionSnippet->setVideoId($videoId);
$captionSnippet->setLanguage($captionLanguage);
$captionSnippet->setName($captionName);
$captionSnippet->setIsDraft( true );

# Create a caption with snippet.
$caption = new Google_Service_YouTube_Caption();
$caption->setSnippet($captionSnippet);

// Setting the defer flag to true tells the client to return a request which can be called
$client->setDefer(false);

// Get the file content of the uploaded file
$file = file_get_contents( $captionFile['tmp_name'] );

// Create a request for the API captions.insert method to create and upload a caption.
$insertRequest = $youtube->captions->insert("snippet", $caption, array( 
  'sync' => true, 
  'data' => $file, 
  'mimeType' => 'application/octet-stream', 
  'uploadType' => 'multipart' )  
); 

echo '<pre>'; print_r( $insertRequest ); echo '</pre>';

// // Read the caption file and upload it chunk by chunk.
$status = $insertRequest;
fclose($handle);

// If you want to make other calls after the file upload, set setDefer back to false
$client->setDefer(false);

Спасибо,
Тайлер Штайнхаус

Ответы

Ответ 1

Вы пытались достичь того, что хотите, используя функции, которые Google разместили сами?

Ниже взято из https://developers.google.com/youtube/v3/code_samples/php

/**
 * Uploads a caption track in draft status that matches the API request parameters.
 * (captions.insert)
 *
 * @param Google_Service_YouTube $youtube YouTube service object.
 * @param Google_Client $client Google client.
 * @param $videoId the YouTube video ID of the video for which the API should
 *  return caption tracks.
 * @param $captionLanguage language of the caption track.
 * @param $captionName name of the caption track.
 * @param $captionFile caption track binary file.
 * @param $htmlBody html body.
 */
function uploadCaption(Google_Service_YouTube $youtube, Google_Client $client, $videoId,
    $captionFile, $captionName, $captionLanguage, &$htmlBody) {
    # Insert a video caption.
    # Create a caption snippet with video id, language, name and draft status.
    $captionSnippet = new Google_Service_YouTube_CaptionSnippet();
    $captionSnippet->setVideoId($videoId);
    $captionSnippet->setLanguage($captionLanguage);
    $captionSnippet->setName($captionName);

    # Create a caption with snippet.
    $caption = new Google_Service_YouTube_Caption();
    $caption->setSnippet($captionSnippet);

    // Specify the size of each chunk of data, in bytes. Set a higher value for
    // reliable connection as fewer chunks lead to faster uploads. Set a lower
    // value for better recovery on less reliable connections.
    $chunkSizeBytes = 1 * 1024 * 1024;

    // Setting the defer flag to true tells the client to return a request which can be called
    // with ->execute(); instead of making the API call immediately.
    $client->setDefer(true);

    // Create a request for the API captions.insert method to create and upload a caption.
    $insertRequest = $youtube->captions->insert("snippet", $caption);

    // Create a MediaFileUpload object for resumable uploads.
    $media = new Google_Http_MediaFileUpload(
        $client,
        $insertRequest,
        '*/*',
        null,
        true,
        $chunkSizeBytes
    );
    $media->setFileSize(filesize($captionFile));


    // Read the caption file and upload it chunk by chunk.
    $status = false;
    $handle = fopen($captionFile, "rb");
    while (!$status && !feof($handle)) {
      $chunk = fread($handle, $chunkSizeBytes);
      $status = $media->nextChunk($chunk);
    }

    fclose($handle);

    // If you want to make other calls after the file upload, set setDefer back to false
    $client->setDefer(false);

    $htmlBody .= "<h2>Inserted video caption track for</h2><ul>";
    $captionSnippet = $status['snippet'];
    $htmlBody .= sprintf('<li>%s(%s) in %s language, %s status.</li>',
        $captionSnippet['name'], $status['id'], $captionSnippet['language'],
        $captionSnippet['status']);
    $htmlBody .= '</ul>';
}

Ответ 2

Я смог воспроизвести эту проблему и нашел возможное исправление. Ключ был содержимым загруженного файла субтитров. Подсказка заключалась в том, что в документации говорится:

Параметр синхронизации указывает, должна ли YouTube автоматически синхронизировать файл подписи со звуковой дорожкой видео. Если вы установите значение true, YouTube будет игнорировать любые временные коды, которые находятся в загруженном файле субтитров, и генерировать новые временные коды для подписей.

Вы должны установить для параметра sync значение true, если вы загружаете стенограмму, которая не имеет временных кодов, или если вы подозреваете, что временные коды в вашем файле неверны и хотите, чтобы YouTube попытался их исправить.

Настройка, которая заставила его работать для меня, заключалась в том, чтобы добавить некоторые фиктивные коды времени, которые, как я знал, были неправильными, и установить 'sync' => 'true',, чтобы служба YouTube исправила их. Например, вот файл .sbv, который работал НЕ:

This is a sample video to test the YouTube API captioning system.

Когда я использовал этот файл, я получил ту же ошибку, что и вы, т.е. Track content is not processed, но когда я сменил ее на нее, это сработало:

00:00:00,00:00:00
This is a sample video to test the YouTube API captioning system.

Когда я загрузил обработанный файл .sbv с YouTube, он выглядел так:

0:00:00.000,0:00:04.266
This is a sample video to test the YouTube
API captioning system.

Конечно, я только пробовал это для ОЧЕНЬ тривиальное видео, и я не думаю, что они сделали очень хорошая работа с таймингами, но, надеюсь, она будет расширяться для работы с вашей системой.