Как реализовать глубокую ссылку в канале Roku VideoPlayer Sample

Мы разработали канал Roku, используя образец канала Roku VideoPlayer (https://github.com/rokudev/videoplayer-channel). Хотя недавняя отправка в Roku была отклонена из-за отсутствия возможности создания прямых ссылок. main.brs предоставляет средства для анализа запроса на глубокую ссылку, которую я смог реализовать для получения моих contentID и mediaType на основе команды curl следующим образом:

curl -d '' 'http://192.168.1.24:8060/launch/dev?MediaType=special&contentID=49479'

Комментарии main.brs говорят

запустить / подготовить контент, сопоставленный с contentID здесь.

Мы используем файлы xml для обеспечения экрана «категорий» Roku и экрана для списка после выбора элемента на экране категорий (включая экран трамплина). В этих xml-файлах мы помечаем contentID и mediaType каждого элемента видео.

Я новичок в разработке Roku. Хотя мы и раньше могли создавать каналы, используя их шаблон видеоканала, я не знаю, как «запустить / подготовить контент, сопоставленный с contentID». Я искал и пробовал различные другие вызовы (например, - playMedia(ContentID, Screen)), но я получаю ошибки в отладчике, связанные с «попыткой вызова функции operator () не для функции».

Я был бы признателен за некоторые инструкции о том, как перейти к трамплину видео на основе значения contentID, переданного с помощью команды глубокой привязки. Или средство для воспроизведения видео на основе contentID в файле xml.

Вот мой main.brs:

sub Main(input as Dynamic)
  print "################"
  print "Start of Channel"
  print "################"
  ' Add deep linking support here. Input is an associative array containing
  ' parameters that the client defines. Examples include "options, contentID, etc."
  ' See guide here: https://sdkdocs.roku.com/display/sdkdoc/External+Control+Guide
  ' For example, if a user clicks on an ad for a movie that your app provides,
  ' you will have mapped that movie to a contentID and you can parse that ID
  ' out from the input parameter here.
  ' Call the service provider API to look up
  ' the content details, or right data from feed for id
  if input <> invalid
    print "Received Input -- write code here to check it!"
    if input.reason <> invalid
      if input.reason = "ad" then
        print "Channel launched from ad click"
        'do ad stuff here
      end if
    end if
    if input.contentID <> invalid
      m.contentID = input.contentID
      print "contentID is: " + input.contentID
      print "mediaType is: " + input.mediaType
      'launch/prep the content mapped to the contentID here

    end if
  end if
  showHeroScreen(input)
end sub

' Initializes the scene and shows the main homepage.
' Handles closing of the channel.
sub showHeroScreen(input as object)
  print "main.brs - [showHeroScreen]"
  screen = CreateObject("roSGScreen")
  m.port = CreateObject("roMessagePort")
  screen.setMessagePort(m.port)
  scene = screen.CreateScene("VideoScene")
  m.global = screen.getGlobalNode()
  'Deep link params
  m.global.addFields({ input: input })
  screen.show()

  while(true)
    msg = wait(0, m.port)
    msgType = type(msg)
    if msgType = "roSGScreenEvent"
      if msg.isScreenClosed() then return
    end if
  end while
end sub

Я думаю, если я смогу правильно настроить параметры для глубокой ссылки до вызова screen.show, это должно сработать? Я могу вывести значения outputID и mediaType с помощью отладчика при использовании curl для вызова глубинной ссылки, но он просто переходит на главный экран, не вызывая видео, которое было глубоко связано.

Любая помощь приветствуется.


person Steve Lacy    schedule 14.12.2017    source источник


Ответы (1)


Пожалуйста, проверьте мой REPO на GitHub простой пример глубокого связывания.

Небольшое объяснение: сначала я ввожу свой main.brs вот так:

sub Main(args as Dynamic) as Void

    showSGScreen(args)
end sub

"args" будет предоставлен прошивкой Roku! В моем showSGScreen Sub вы найдете:

'DeepLinking
if args.contentId <> invalid AND args.mediaType <> invalid
    m.scene.contentDLId = args.contentId
    m.scene.mediaDPType = args.mediaType
    m.scene.deepLinkingLand = true
end if

А теперь посмотрите мой файл audiocontent.xml:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<AudioContent>
  <audio actors = "Artist - Unknown" album ="Album - Unknown" title = "KISS FM - LIVE STREAM" streamformat = "es.aac-adts" url = "http://80.86.106.143:9128/kissfm.aacp" HDPosterUrl = "pkg:/images/radio_stations_img/kiss_fm.png" Rating = "true" TrackIDAudio = "1" ShortDescriptionLine1 = "short-form"/>
  <audio actors = "Artist - Unknown" album ="Album - Unknown" title = "TDI Radio - LIVE STREAM" streamformat = "mp3" url = "http://streaming.tdiradio.com:8000/tdiradiob" HDPosterUrl = "pkg:/images/radio_stations_img/tdi_radio.png" Rating = "true" TrackIDAudio = "2" ShortDescriptionLine1 = "short-form"/>
  <audio actors = "Artist - Unknown" album ="Album - Unknown" title = "Polskie Radio - LIVE STREAM" streamformat = "hls" url = "http://stream85.polskieradio.pl/omniaaxe/k11.stream/playlist.m3u8" HDPosterUrl = "pkg:/images/radio_stations_img/polskie_radio.png" Rating = "true" TrackIDAudio = "3" ShortDescriptionLine1 = "short-form"/>
  <audio actors = "Edgar Allan Yo and Shporky Pork" album ="Mony Pajton EP" title = "Niko kao Ja - MP3" streamformat = "mp3" url = "pkg:/mp3/Edgar_Allan_Yo_and_Shporky_Pork_Niko_Kao_Ja.mp3"    HDPosterUrl = "pkg:/images/mp3_img/mony_pajton.png" Rating = "false" TrackIDAudio = "4" ShortDescriptionLine1 = "short-form"/>
  <audio actors = "Edgar Allan Yo and Shporky Pork" album ="Mony Pajton EP" title = "Zatvaramo Krug - MP3" streamformat = "mp3" url = "pkg:/mp3/Edgar_Allan_Yo_and_Shporky_Pork_Zatvaramo_Krug.mp3" HDPosterUrl = "pkg:/images/mp3_img/mony_pajton.png" Rating = "false" TrackIDAudio = "5" ShortDescriptionLine1 = "short-form"/>
</AudioContent>

Обратите внимание на свойство TrackIDAudio.

Теперь перейдите в файл HomeSceen.brs и посмотрите на это:

if m.audiolist.content.getChild(index).TrackIDAudio = m.contentId
                    m.audiolist.jumpToItem = index
                    m.audioPlayer.itemContent = m.audiolist.content.getChild(index)
                    m.audioPlayer.audioControl = "play"
                    m.audioPlayer.setFocus(true)
                    m.audioPlayer.visible = true 

                    exit for
end if

Итак, здесь я проверяю, совпадает ли m.contentId (на самом деле это args.contentId, который мы добавили обратно в файл main.brs в начало HomeScene) с TrackIDAudio из моего списка LabelList. Если они совпадают, приложение воспроизведет мой элемент!

Во-первых, вы можете проверить свои внутренние ссылки с помощью этого ИНСТРУМЕНТА.

Кроме того, теперь вам нужно будет отправить XML-канал Roku с вашими идентификаторами контента и MediaTypes, чтобы они могли связать эти элементы с вашим приложением при публикации.

Таким образом, пользователь нажимает на ваш элемент в поиске Roku, Roku отправляет contentId и MediaType, которые вы предоставили им в канале XML, в прошивку Roku, прошивку ROKU, затем помещает contentId и MediaType в аргументы, и после этого вы делаете с ними то, что вам нужно. Инструмент глубоких ссылок имитирует это.

Также вы можете найти дополнительную информацию о глубоких ссылках на эту ссылку

*** Один элемент в моем audiocontent.xml имеет плохую ссылку. Я сделал это намеренно, чтобы показать, что произойдет, если вы проиграете поврежденную ссылку. Поэтому, пожалуйста, не беспокойтесь об этом, играя с Repo.

*** Пожалуйста, проверьте это относительно изменений в вашем вопросе: Хорошо, вы можете сделать это и так: Удалите эту строку m.global.addFields({ input: input }) и добавьте эти две:

m.global.addFields({inputContentID: input.contentID})
m.global.addFields({inputMediaType: input.mediaType})

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

if Len(m.global.inputContentID) > 0 AND Len(m.global.inputMediaType) > 0

        //loop through your content and find an item that has same inputContentID as the one saved in m.global.inputContentID variable.If you find it, play the video.

        m.Video.control = "play"

        m.global.inputContentID = ""
        m.global.inputMediaType = ""
end if
person U.Mitic    schedule 15.12.2017
comment
Мой основной канал использует шаблон видео, поэтому у меня даже нет HomeScreen.brs в папке с компонентами. У меня возникли проблемы с переводом вашего примера на пример шаблона видео. Я думаю, если бы я мог просто выяснить, как правильно передать параметры функции video screen.show, это могло бы сработать? Спасибо! - person Steve Lacy; 27.12.2017
comment
Привет, я добавил несколько строк к своему ответу выше. Надеюсь, это поможет! - person U.Mitic; 27.12.2017
comment
Извините, но я все еще не могу перевести ваш пример на видео. Я пробовал несколько вещей, но они у меня не работают. Я получаю такие ошибки, как «Несоответствие типов» или «Использование неинициализированной переменной» при попытке добавить код в мой код SpringBoard.brs или VideoScene.brs. Думаю, я близок, но у меня это не работает. - person Steve Lacy; 05.01.2018
comment
Можете ли вы сказать мне, для какой переменной вы получаете несоответствие типов или использование неинициализированной переменной? - person U.Mitic; 05.01.2018
comment
@SteveLacy Можете ли вы сказать мне, какая переменная дала вам использовать неинициализированную переменную или ошибку несоответствия типов? - person U.Mitic; 05.01.2018
comment
Я делал несколько простых вещей, например, имел оператор печати сразу после присвоения m.global.addFields ({inputContentID: input.contentID}) со строкой: print contentID is: + inputContentID в main.brs и получил ошибку о неинициализированном inputContentID . Я не разработчик brightscript, но знаю другие языки, поэтому подумал, что простой оператор печати сработает. Я использую шаблон видеоплеера Roku и создаю необходимый XML с помощью некоторых сценариев php на стороне сервера. Я следил за выводом через telnet для своего канала, пытаясь выяснить, куда загрузить условный оператор. - person Steve Lacy; 05.01.2018
comment
Хорошо, я понял ... причина этой ошибки в том, что вы печатаете inputContentID, но для печати данных, которые вы добавили в m.global.addFields ({inputContentID: input.contentID}), вам нужно будет распечатать это так: print contentID:; m.global.inputContentID. - person U.Mitic; 06.01.2018