Статьи

API YouTube, версия 3 на Rails

Старый значок YouTube

Некоторое время назад я написал статью об использовании YouTube на Rails , в которой объясняются основы взаимодействия с API YouTube. В предыдущей статье рассказывалось о том, как получить видеоинформацию и использовать API IFrame YouTube для управления видеоплеером. Позже была опубликована еще одна статья, « Загрузка видео на YouTube с помощью Rails» , показывающая, как создать приложение, позволяющее пользователям загружать видео непосредственно на YouTube.

Жемчужина Youtube_it использовалась для обеих демонстраций. Оба моих поста собрали немало комментариев, которые я ценю.

youtube_it — это замечательная жемчужина, однако в нем используется версия 2 API YouTube, которая официально объявлена ​​устаревшей и больше не будет поддерживаться после 20 апреля 2015 года . Уч.

К счастью, Claudiofullscreen спас этот день, создав новый гем под названием yt (теперь это короткое имя), который использует версию 3 API YouTube.

В этой статье мы собираемся создать приложение, подобное тому, которое было представлено в постах «YouTube on Rails» и «Загрузка видео на YouTube с Rails», но сделаем так, чтобы оно работало с версией 3 API YouTube.

Рабочая демоверсия доступна по адресу sitepoint-ytv3.herokuapp.com .

Исходный код доступен на GitHub .

Изменения в V3

Есть некоторые заметные изменения в v3:

  • Аутентификация В то время как API v2 допускает аутентификацию через OAuth, OAuth 2, AuthSub или Developer Key (для выполнения запросов только для чтения), API v3 поддерживает только OAuth 2 . С OAuth 2 вы можете получить доступ к личным данным пользователя и манипулировать ими через API. Доступ только для чтения, не требующий аутентификации пользователя, также поддерживается. Вам нужно предоставить ключ API, который идентифицирует ваш проект, который я покажу вам чуть позже.
  • Загрузка видео . Извлечение видео по тэгам и поиск наиболее связанных видео больше не поддерживается. Расширенные запросы с логическими операторами также были удалены.
  • Нет больше комментариев для вас . По крайней мере, на данный момент, поскольку YouTube перерабатывает свою систему комментирования , поэтому комментарии в настоящее время не являются частью API. Это означает, что вы больше не можете просматривать или оставлять комментарии к видео.
  • Видеоответы были удалены . ПОКОЙСЯ С МИРОМ. Как говорится в этом объявлении , видеоответы использовались примерно в 0,0004% случаев, поэтому команда YouTube решила удалить его.
  • Списки контроля доступа . Большая часть этой функциональности была удалена; единственный, который остается, является embeddable , однако есть сообщения, что это не работает также.

Вы можете обратиться к Руководству по миграции, чтобы узнать больше. Кстати, для тех, кто переходит с гема youtube_it на yt , есть специальное руководство .

Подготовка приложения

Я собираюсь создать приложение, которое будет предоставлять следующие функции:

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

В этом руководстве я собираюсь придерживаться Rails 4.2.0, но такое же решение (с очень небольшим количеством модификаций) можно реализовать с помощью Rails 3 и 4.1.

Начните с создания нового приложения без набора тестов по умолчанию:

 $ rails new YtVideosV3 -T 

Перетащите следующие драгоценные камни в свой Gemfile:

Gemfile

 [...] gem 'yt', '~> 0.13.7' gem 'bootstrap-sass', '~> 3.3.0.1' gem 'autoprefixer-rails' [...] 

Главная звезда здесь — это Yt . Я использую Bootstrap для стилизации, но это не обязательно. autoprefixer-rails рекомендуется для использования с Bootstrap для автоматического добавления префиксов поставщиков браузера.

Не забудь бежать

 $ bundle install 

Подключите Bootstrap:

application.scss

 @import "bootstrap-sprockets"; @import "bootstrap"; @import 'bootstrap/theme'; 

Хорошо, теперь немного подправим макет:

макеты / application.html.erb

 [...] <div class="navbar navbar-inverse"> <div class="container"> <div class="navbar-header"> <%= link_to 'YT APIv3', root_path, class: 'navbar-brand' %> </div> <ul class="nav navbar-nav"> <li><%= link_to 'Videos', root_path %></li> <li><%= link_to 'Add Video', new_video_path %></li> </ul> </div> </div> <div class="container"> <% flash.each do |key, value| %> <div class="alert alert-<%= key %>"> <%= value %> </div> <% end %> </div> [...] 

Затем перейдите к модели Video , которая будет хранить видео пользователей. Он будет содержать следующие атрибуты:

  • link ( string ) — ссылка на видео на YouTube
  • uid ( string ) — уникальный идентификатор видео, представленный YouTube. Это хорошая идея, чтобы добавить индекс базы данных здесь
  • title ( string ) — название видео
  • datetime ( datetime ) — дата публикации видео на YT
  • likes ( integer ) — лайки для видео
  • dislikes ( integer ) — не любит рассчитывать на видео

Создайте и примените соответствующую миграцию:

 $ rails g model Video link:string title:string published_at:datetime likes:integer dislikes:integer uid:string:index $ rake db:migrate 

Не забудьте настроить маршруты:

конфиг / routes.rb

 [...] resources :videos, only: [:index, :new, :create] root to: 'videos#index' [...] 

Создайте контроллер:

videos_controller.rb

 class VideosController < ApplicationController def index @videos = Video.order('created_at DESC') end def new @video = Video.new end def create end end 

На странице index отобразите все видео, которые были добавлены пользователем. Также будет new страница, которая представляет форму для добавления нового видео. Действие create будет подробно описано в следующем разделе.

Наконец, создайте index представление с одной кнопкой:

просмотры / видео / index.html.erb

 <div class="jumbotron"> <div class="container"> <h1>Share your videos with the world!</h1> <p>Click the button below to share your video from YouTube.</p> <p> <%= link_to 'Add video now!', new_video_path, class: 'btn btn-primary btn-lg' %> </p> </div> </div> 

Добавление видео с YouTube

Следующим шагом является создание формы для добавления видео, которые ранее были загружены на YouTube, то есть вне нашего приложения. Единственное, что нам нужно знать, — это ссылка на видео, которое пользователь хочет добавить. Вся остальная информация об этом будет найдена с помощью API YouTube. Таким образом, форма очень проста:

просмотры / видео / new.html.erb

 <div class="container"> <h1>New video</h1> <%= form_for @video do |f| %> <%= render 'shared/errors', object: @video %> <div class="form-group"> <%= f.label :link %> <%= f.text_field :link, class: 'form-control', required: true %> <span class="help-block">A link to the video on YouTube.</span> </div> <%= f.submit class: 'btn btn-primary' %> <% end %> </div> 

Часть shared/_errors.html.erb используется здесь:

просмотров / общий / _errors.html.erb

 <% if object.errors.any? %> <div class="panel panel-danger"> <div class="panel-heading"> <h3 class="panel-title">The following errors were found while submitting the form:</h3> </div> <div class="panel-body"> <ul> <% object.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> </div> <% end %> 

Теперь create действие:

videos_controller.rb

 [...] def create @video = Video.new(video_params) if @video.save flash[:success] = 'Video added!' redirect_to root_url else render :new end end private def video_params params.require(:video).permit(:link) end [...] 

Действительно просто. Давайте также настроим проверку, чтобы пользователи не могли вводить недействительные ссылки:

модели / video.rb

 class Video < ActiveRecord::Base YT_LINK_FORMAT = /\A.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/i validates :link, presence: true, format: YT_LINK_FORMAT end 

Настройка YT API

Прежде чем двигаться дальше, нам нужно настроить гем yt, чтобы он мог взаимодействовать с API YouTube. Прежде всего, перейдите в консоль разработчиков Google и создайте новое приложение. Называйте его как угодно, но имейте в виду, что пользователи увидят это имя при аутентификации через OAuth 2. Затем перейдите на страницу экрана «Согласие» (раздел API и аутентификация) и предоставьте основную информацию о вашем приложении.

Откройте страницу API и включите следующее:

  • Google+ API
  • API YouTube Analytics
  • API данных YouTube v3

Если вы забудете включить некоторые из них, при попытке связаться с YT API будут возникать ошибки. Также обратите внимание, что API имеют квоты на использование, поэтому имейте в виду, сколько вы отправляете в API.

Последний шаг — получение ключа сервера для запросов к общедоступному API, поскольку в настоящее время нам не нужно никакого взаимодействия с пользователем — будут выполняться только основные действия. Перейдите к учетным данным и нажмите «Создать новый ключ» в разделе доступа «Открытый API». Затем выберите ключ сервера и введите IP-адрес вашего сервера, чтобы запросы не могли отправляться с других IP-адресов.

Если вы не уверены, какой IP ввести, просто оставьте это поле пустым (что фактически означает
что любому IP разрешено отправлять запросы с предоставленным ключом сервера) — в конце концов, мы создаем демонстрационное приложение. Наконец, нажмите «Создать» — новый ключ для серверных приложений будет добавлен. Значение ключа API — это то, что нам нужно.

Создайте файл инициализатора для настройки yt:

конфиг / Инициализаторы / yt.rb

 Yt.configure do |config| config.api_key = 'your_server_key' end 

Этот ключ API должен храниться в безопасности — я использую переменную окружения для его хранения.

Теперь yt настроен и может выдавать запросы API для получения основной информации, такой как название видео или дата публикации.

Опрос API YT

Перед сохранением видео в базе данных информацию о нем следует загрузить с YouTube. В статье «YouTube on Rails» я использовал before_create вызов before_create чтобы получить всю необходимую информацию, но один из читателей отметил, что наблюдатель также может быть использован для этой задачи, поэтому давайте попробуем это вместо этого.

В Rails 4 наблюдатели больше не являются частью ядра фреймворка, поэтому нам нужен отдельный гем, чтобы вернуть их:

Gemfile

 [...] gem 'rails-observers' [...] 

Бегать

 $ bundle install 

и настроить конфигурацию приложения, как это

конфиг / application.rb

 [...] config.active_record.observers = :video_observer [...] 

зарегистрировать нового наблюдателя.

Создайте наблюдателя в каталоге моделей :

модели / video_observer.rb

 class VideoObserver < ActiveRecord::Observer def before_save(resource) video = Yt::Video.new url: resource.link resource.uid = video.id resource.title = video.title resource.likes = video.like_count resource.dislikes = video.dislike_count resource.published_at = video.published_at rescue Yt::Errors::NoItems resource.title = '' end end 

Метод before_save будет запущен только перед сохранением записи. Этот метод принимает ресурс в качестве аргумента. Внутри метода я использую Yt::Video.new для получения указанного видео через API по его URL. Затем мы просто используем методы yt, чтобы получить всю необходимую информацию.

Я также Yt::Errors::NoItems ошибки Yt::Errors::NoItems — это произойдет, когда запрошенное видео не было найдено.

Это все! Вы можете пойти дальше и добавить несколько видео на ваш выбор, чтобы проверить, все ли работает правильно.

Отображение видео

Давайте потратим пару минут на изменение страницы index чтобы показывать видео. Используйте следующий макет:

просмотры / видео / index.html.erb

 <div class="jumbotron"> <div class="container"> <h1>Share your videos with the world!</h1> <p>Click the button below to share your video from YouTube.</p> <p> <%= link_to 'Add video now!', new_video_path, class: 'btn btn-primary btn-lg' %> </p> </div> </div> <% if @videos.any? %> <div class="container"> <h1>Latest videos</h1> <div id="player-wrapper"></div> <% @videos.in_groups_of(3) do |group| %> <div class="row"> <% group.each do |video| %> <% if video %> <div class="col-md-4"> <div class="yt_video thumbnail"> <%= link_to image_tag("https://img.youtube.com/vi/#{video.uid}/mqdefault.jpg", alt: video.title, class: 'img-rounded'), "https://www.youtube.com/watch?v=#{video.uid}", target: '_blank' %> <div class="caption"> <h5><%= video.title %></h5> <p>Published at <%= video.published_at.strftime('%-d %B %Y %H:%M:%S') %></p> <p> <span class="glyphicon glyphicon glyphicon-thumbs-up"></span> <%= video.likes %> <span class="glyphicon glyphicon glyphicon-thumbs-down"></span> <%= video.dislikes %> </p> </div> </div> </div> <% end %> <% end %> </div> <% end %> </div> <% end %> 

in_groups_of — это метод Rails, который делит массив видео на группы по 3 элемента. Затем мы перебираем каждую группу для их рендеринга. Обратите внимание на условие if video — это необходимо, потому что, если у вас есть, например, 5 элементов в массиве и разделите их на группы по 3, последний элемент будет установлен в nil .

Для каждого видео отобразите его уменьшенное изображение, которое YouTube создает для нас. mqdefault.jpg означает, что мы хотим получить изображение размером 320 × 180 без черных полос выше и ниже изображения. Существует также hqdefault.jpg (изображение 480 × 360 с черными полосами выше и ниже изображения) и <1,2,3> .jpg (изображение 120 × 90 с различными сценами из видео с черными полосами выше и ниже изображения ).

Каждый эскиз действует как ссылка на видео на YouTube. В статье «YouTube on Rails» я показал, как реализовать API IFrame YouTube, чтобы добавить проигрыватель на свою страницу (и управлять им). Этот процесс не изменился вообще, поэтому нет необходимости дублировать тот же код здесь. Просмотрите раздел « Отображение видео » в этой статье для получения дополнительной информации.

Загрузка видео на YouTube

Прямо сейчас пользователи могут легко добавлять свои видео в наше приложение. Что если у кого-то есть видео, которое еще не загружено на YouTube? Должны ли мы поручить этому человеку сначала использовать YT Video Manager для загрузки файла, а затем использовать интерфейс нашего приложения для обмена видео? Было бы удобнее, если бы пользователи могли просто загружать свои видео напрямую через наше приложение.

Аутентификация через Google+

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

Мы собираемся использовать omniauth-google-oauth2, который предоставляет стратегию Google OAuth 2 для OmniAuth .

Добавьте новый драгоценный камень в Gemfile :

Gemfile

 [...] gem 'omniauth-google-oauth2' [...] 

и беги

 $ bundle install 

Создайте инициализатор, который будет содержать настройки для нашей стратегии аутентификации:

конфиг / Инициализаторы / omniauth.rb

 Rails.application.config.middleware.use OmniAuth::Builder do provider :google_oauth2, 'YT_CLIENT_ID', 'YT_CLIENT_SECRET', scope: 'userinfo.profile,youtube' end 

Мы регистрируем новую стратегию под названием google_oauth2 . YT_CLIENT_ID и YT_CLIENT_SECRET можно получить через консоль разработчика Google , которую мы использовали несколько минут назад. Вернитесь туда, откройте приложение, которое вы создали ранее, и перейдите к учетным данным. Нажмите кнопку «Создать новый идентификатор клиента» и выберите «Веб-приложение». Введите URL своего сайта в поле «Authorized JavaScript» origin (используйте «http://127.0.0.1:3000», если работаете на компьютере разработчика).

Для URI авторизованного перенаправления укажите URL-адрес сайта плюс «/ auth / google_oauth2 / callback» (например,
«Http://127.0.0.1:3000/auth/google_oauth2/callback»). Будет создан новый идентификатор клиента для веб-приложения. Поля Client ID и Client Secret — это то, что вы хотите. Еще раз, эти ключи не должны быть доступны в вашей системе контроля версий.

Последний параметр нашей стратегии — это scope , которая определяет, какие действия приложение хочет выполнить. userinfo.profile означает, что мы хотим иметь возможность получать основную информацию об учетной записи пользователя (например, имя, уникальный идентификатор и тому подобное). youtube означает, что приложение сможет управлять учетной записью YouTube пользователя (потому что мы должны иметь возможность загружать новые видео).

Добавьте еще пару маршрутов:

конфиг / routes.rb

 [...] get '/auth/:provider/callback', to: 'sessions#create' delete '/logout', to: 'sessions#destroy', as: :logout [...] 

Первый — это маршрут обратного вызова, по которому пользователь перенаправляется после успешной аутентификации. Второй маршрут будет использоваться для выхода из системы.

Нам нужно где-то хранить данные пользователя, поэтому потребуется новая таблица. Давайте назовем это users . На данный момент он будет содержать следующие поля:

  • name ( string ) — имя пользователя (возможно, с фамилией).
  • token ( string ) — токен для выполнения запросов API.
  • uid ( string ) — уникальный идентификатор пользователя. Мы собираемся добавить индекс с ограничением уникальности здесь.

Создайте миграцию:

 $ rails g model User name:string token:string uid:string 

и добавьте эту строку сразу после метода create_table :

xxx_create_users.rb

 [...] create_table :users do |t| [...] end add_index :users, :uid, unique: true [...] 

Нам также нужен новый контроллер с двумя действиями:

sessions_controller.rb

 class SessionsController < ApplicationController def create user = User.from_omniauth(request.env['omniauth.auth']) session[:user_id] = user.id flash[:success] = "Welcome, #{user.name}" redirect_to root_url end def destroy session[:user_id] = nil flash[:success] = "Goodbye!" redirect_to root_url end end 

request.env['omniauth.auth'] содержит всю информацию, отправляемую сервером нашему приложению (это называется «хэш аутентификации»). Теперь давайте создадим метод from_omniauth :

модели / user.rb

 class User < ActiveRecord::Base class << self def from_omniauth(auth) user = User.find_or_initialize_by(uid: auth['uid']) user.name = auth['info']['name'] user.token = auth['credentials']['token'] user.save! user end end end 

Здесь find_or_initialize_by метод find_or_initialize_by . Он пытается найти пользователя с предоставленным uid и, если он найден, в результате возвращается запись. Если он не найден, новый объект создается и возвращается. Это сделано, чтобы избежать ситуаций, когда один и тот же пользователь создается несколько раз. Затем мы получаем имя пользователя и токен, сохраняем запись и возвращаем ее.

Вот пример аутентификационного хэша, который вы можете использовать в качестве ссылки.

Настало время создать новый метод для проверки того, вошел ли пользователь. Мы будем называть его current_user , что является распространенной идиомой в проектах Rails.

application_controller.rb

 [...] private def current_user @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id] end helper_method :current_user [...] 

Он просто проверяет, содержит ли сеанс user_id и, если это так, пытается найти пользователя с указанным идентификатором. helper_method гарантирует, что этот метод также может быть использован в представлениях.

Наконец, давайте немного расширим наше меню:

просмотров / макеты / application.html.erb

 [...] <div class="navbar navbar-inverse"> <div class="container"> <div class="navbar-header"> <%= link_to 'YT APIv3', root_path, class: 'navbar-brand' %> </div> <ul class="nav navbar-nav"> <li><%= link_to 'Videos', root_path %></li> <li><%= link_to 'Add Video', new_video_path %></li> <% if current_user %> <li><%= link_to 'Upload Video', new_video_upload_path %></li> <% end %> </ul> <ul class="nav navbar-nav pull-right"> <% if current_user %> <li><span><%= current_user.name %></span></li> <li><%= link_to 'Log Out', logout_path, method: :delete %></li> <% else %> <li><%= link_to 'Log In', '/auth/google_oauth2' %></li> <% end %> </ul> </div> </div> [...] 

Я также добавил несколько стилей для красивого оформления этих ссылок:

application.scss

 [...] .nav > li > span { display: block; padding-top: 15px; padding-bottom: 15px; color: #9d9d9d; } 

Выгрузка

Отлично, остался только один шаг. Мы должны создать другую форму, позволяющую пользователю выбрать видео и предоставить название и описание для него.

Мы могли бы использовать тот же VideosController , но я решил использовать другой подход, который следует принципам REST и делает проверку действительно простой.

Создайте новый контроллер:

video_uploads_controller.rb

 class VideoUploadsController < ApplicationController def new @video_upload = VideoUpload.new end def create end end 

Мы скоро вернемся к методу create . А пока добавьте новые маршруты:

конфиг / routes.rb

 [...] resources :video_uploads, only: [:new, :create] [...] 

и еще один пункт меню:

просмотров / макеты / application.html.erb

 [...] <ul class="nav navbar-nav"> <li><%= link_to 'Videos', root_path %></li> <% if current_user %> <li><%= link_to 'Add Video', new_video_upload_path %></li> <% end %> </ul> [...] 

Теперь актуальная форма:

просмотров / video_uploads / new.html.erb

 <div class="container"> <h1>Upload video</h1> <% if current_user %> <%= form_for @video_upload do |f| %> <%= render 'shared/errors', object: @video_upload %> <div class="form-group"> <%= f.label :file %> <%= f.file_field :file, class: 'form-control', required: true %> </div> <div class="form-group"> <%= f.label :title %> <%= f.text_field :title, class: 'form-control', required: true %> </div> <div class="form-group"> <%= f.label :description %> <%= f.text_area :description, class: 'form-control', cols: 3 %> </div> <%= f.submit 'Upload', class: 'btn btn-primary' %> <% end %> <% else %> <p>Please <%= link_to 'sign in', '/auth/google_oauth2' %>.</p> <% end %> </div> 

Мы должны проверить, вошел ли пользователь в систему, иначе попытка загрузить видео приведет к ошибке. Форма содержит три поля: файл , заголовок и описание . Вы можете расширить его, позволяя пользователям предоставлять, например, теги или категории для своего видео (не забудьте соответственно настроить контроллер и модель).

Нам нужно подумать о проверке. Очевидно, нам здесь не нужна отдельная таблица, потому что информация о загруженном видео будет сохранена в той же таблице videos которая уже существует. Таким образом, кажется, что модель не обязательна, но тогда вся логика проверки должна быть помещена в контроллер, что не является лучшей идеей:

 def create if params[:file].present? && params[:title].present? # ... and more checks here # upload video else # display an error (and user won't even understand what exactly is wrong) end end 

Вместо этого создайте класс Ruby и назовите его VideoUpload — там можно поместить всю логику проверки. Однако было бы неплохо, если бы этот класс позаимствовал некоторые классные функции ActiveRecord. Мы можем сделать это, у нас есть технологии. Встречайте active_type, созданный людьми из Макандры. ActiveType делает объекты Ruby шарлатанскими как ActiveRecord.

Бросьте этот драгоценный камень в Gemfile

 [...] gem 'active_type', '0.3.1' [...] 

и беги

 $ bundle install 

Теперь создайте файл video_upload.rb в каталоге моделей :

модели / video_upload.rb

 class VideoUpload < ActiveType::Object attribute :file, :string attribute :title, :string attribute :description, :text validates :file, presence: true validates :title, presence: true end 

К сожалению, существует проблема с Postgres и Rails 4.2 (может быть, также с какой-то другой версией Rails), которая потребовала, чтобы я изменил вторую и третью строки следующим образом:

модели / video_upload.rb

 [...] attribute :file, :varchar attribute :title, :varchar [...] 

Это простой класс Ruby, который наследуется от ActiveType::Object , что дает ему суперсилы. С помощью метода attribute мы указываем атрибуты и типы. Метод validates происходит непосредственно от ActiveRecord, и вы можете использовать его таким же образом. Довольно круто!

В этот момент мы можем вернуться к контроллеру

video_uploads_controller.rb

 def create @video_upload = VideoUpload.new(title: params[:video_upload][:title], description: params[:video_upload][:description], file: params[:video_upload][:file].try(:tempfile).try(:to_path)) if @video_upload.save uploaded_video = @video_upload.upload!(current_user) # check if the video was uploaded or not redirect_to root_url else render :new end end 

Это просто основной метод контроллера. Конечно, вызов save в @video_upload на самом @video_upload ничего не сохраняет — он только запускает проверки. upload! Метод еще не существует, поэтому давайте исправим это:

модели / video_upload.rb

 [...] def upload!(user) account = Yt::Account.new access_token: user.token account.upload_video self.file, title: self.title, description: self.description end [...] 

Этот метод создает нового клиента yt с токеном доступа, который мы получили ранее. Метод upload_video начинает фактическую загрузку. Он принимает параметры файла и видео, такие как заголовок и описание. Если вы прочитали мою статью «Загрузка видео на YouTube с помощью Rails», то, вероятно, заметили, что процесс загрузки теперь стал намного проще. Для YT API v2 вам фактически пришлось выполнить два запроса: первый вернул токен загрузки, а второй позволил начать загрузку. Это было действительно грязно, и, спасибо Google, они упростили вещи.

Последний кусок логики create :

 [...] def create @video_upload = VideoUpload.new(title: params[:video_upload][:title], description: params[:video_upload][:description], file: params[:video_upload][:file].try(:tempfile).try(:to_path)) if @video_upload.save uploaded_video = @video_upload.upload!(current_user) if uploaded_video.failed? flash[:error] = 'There was an error while uploading your video...' else Video.create({link: "https://www.youtube.com/watch?v=#{uploaded_video.id}"}) flash[:success] = 'Your video has been uploaded!' end redirect_to root_url else render :new end end [...] 

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

Кстати, есть другие проверки статуса, кроме failed? — проверьте примеры здесь .

Некоторые Gotchas

Вы должны помнить, что YouTube потребуется некоторое время, чтобы переварить видео, и чем дольше видео, тем больше времени займет этот процесс. Почему ты должен заботиться? Потому что если вы попытаетесь получить продолжительность видео сразу после завершения процесса загрузки, в результате будет возвращено ноль секунд.

То же самое относится и к миниатюрным изображениям — они не будут доступны в течение нескольких минут, вместо этого вы увидите скучное серое изображение по умолчанию.

Чтобы преодолеть эту проблему, вы можете настроить некоторый фоновый процесс, который периодически проверяет, были ли перезаписаны новые загруженные видео (используйте processed? Метод). Если да, получите всю их информацию. Возможно, вы даже захотите скрыть эти видео и отобразить их на главной странице только после окончания анализа. Только не забудьте предупредить своих пользователей об этом факте (разбор длинных видео может занять более 10 минут).

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

Вывод

Это все на сегодня, ребята! Я надеюсь, что вы найдете эту статью столь же полезной, как и оригинальные версии. У yt gem есть много интересных функций, так что просмотрите его readme ! Вы уже использовали YT API v3? Что вы думаете об этом? Сталкивались ли вы с какими-то конкретными проблемами?

Также не стесняйтесь оставлять свои вопросы или запросы на темы, которые вы хотите, чтобы я освещал. Увидимся!