title: Trouble playing vid pre-roll ad in Roku
body: <p>I'm trying to add VAST video pre-roll ads to the <a href="https://blog.roku.com/developer/2016/03/03/scenegraph-tutorial/" rel="nofollow noreferrer">SThree sample Roku SDK project</a> (the "Simple Grid with Video and Details page (.zip)" version).</p>
  
  <p>I can get it to work on app start by putting the following code into <code>main.brs</code>:</p>
  
  <pre><code>library "Roku_Ads.brs"
  ...
  Sub RunUserInterface()
      ...
      raf = Roku_Ads() 
      raf.setAdPrefs(false)       'disable back-filled ads
      raf.setDebugOutput(true)
      raf.setAdUrl("http://pubads.g.doubleclick.net/gampad/ads?slotname=/82114269/Video/fallbacktest&amp;sz=1920x1080&amp;url=[http://roku.com&amp;unviewed_position_start=1&amp;output=vast&amp;impl=s&amp;env=vp&amp;gdfp_req=1&amp;ad_rule=0&amp;description_url=http%3A%2F%2Fapps.roku.com&amp;vad_type=linear&amp;sdkv=roku&amp;min_ad_duration=0&amp;max_ad_duration=60000&amp;rdid=ROKU_ADS_TRACKING_ID&amp;is_lat=ROKU_ADS_LIMIT_TRACKING&amp;idtype=rida&amp;correlator=ROKU_ADS_TIMESTAMP&amp;scor=ROKU_ADS_TIMESTAMP&amp;pod=POD_NUM&amp;ppos=POD_POSITION&amp;cust_params=genre%3DROKU_ADS_CONTENT_GENRE%26ua%3DROKU_ADS_USER_AGENT%26ai%3DROKU_ADS_APP_ID]http://roku.com&amp;unviewed_position_start=1&amp;output=vast&amp;impl=s&amp;env=vp&amp;gdfp_req=1&amp;ad_rule=0&amp;description_url=http%3A%2F%2Fapps.roku.com&amp;vad_type=linear&amp;sdkv=roku&amp;min_ad_duration=0&amp;max_ad_duration=60000&amp;rdid=ROKU_ADS_TRACKING_ID&amp;is_lat=ROKU_ADS_LIMIT_TRACKING&amp;idtype=rida&amp;correlator=ROKU_ADS_TIMESTAMP&amp;scor=ROKU_ADS_TIMESTAMP&amp;pod=POD_NUM&amp;ppos=POD_POSITION&amp;cust_params=genre%3DROKU_ADS_CONTENT_GENRE%26ua%3DROKU_ADS_USER_AGENT%26ai%3DROKU_ADS_APP_ID") 
      adPods = raf.getAds()
      shouldPlayContent = raf.showAds(adPods)
  </code></pre>
  
  <p>I however don't want to play an ad on startup, I want to play an ad before a video play.  So I figure I can just add the lines above to <code>components/screens/DetailsScreen/DetailsScreen.brs</code>:</p>
  
  <pre><code>' on Button press handler
  Sub onItemSelected()
      ' first button is Play
      if m.top.itemSelected = 0
          'START ADDING FOR PRE-ROLL
          raf = Roku_Ads() 
          raf.setAdPrefs(false)       'disable back-filled ads
          raf.setDebugOutput(true)
          raf.setAdUrl("http://pubads.g.doubleclick.net/gampad/ads?slotname=/82114269/Video/fallbacktest&amp;sz=1920x1080&amp;url=[http://roku.com&amp;unviewed_position_start=1&amp;output=vast&amp;impl=s&amp;env=vp&amp;gdfp_req=1&amp;ad_rule=0&amp;description_url=http%3A%2F%2Fapps.roku.com&amp;vad_type=linear&amp;sdkv=roku&amp;min_ad_duration=0&amp;max_ad_duration=60000&amp;rdid=ROKU_ADS_TRACKING_ID&amp;is_lat=ROKU_ADS_LIMIT_TRACKING&amp;idtype=rida&amp;correlator=ROKU_ADS_TIMESTAMP&amp;scor=ROKU_ADS_TIMESTAMP&amp;pod=POD_NUM&amp;ppos=POD_POSITION&amp;cust_params=genre%3DROKU_ADS_CONTENT_GENRE%26ua%3DROKU_ADS_USER_AGENT%26ai%3DROKU_ADS_APP_ID]http://roku.com&amp;unviewed_position_start=1&amp;output=vast&amp;impl=s&amp;env=vp&amp;gdfp_req=1&amp;ad_rule=0&amp;description_url=http%3A%2F%2Fapps.roku.com&amp;vad_type=linear&amp;sdkv=roku&amp;min_ad_duration=0&amp;max_ad_duration=60000&amp;rdid=ROKU_ADS_TRACKING_ID&amp;is_lat=ROKU_ADS_LIMIT_TRACKING&amp;idtype=rida&amp;correlator=ROKU_ADS_TIMESTAMP&amp;scor=ROKU_ADS_TIMESTAMP&amp;pod=POD_NUM&amp;ppos=POD_POSITION&amp;cust_params=genre%3DROKU_ADS_CONTENT_GENRE%26ua%3DROKU_ADS_USER_AGENT%26ai%3DROKU_ADS_APP_ID") 
          adPods = raf.getAds()
          shouldPlayContent = raf.showAds(adPods)
          'END ADDING FOR PRE-ROLL
  
          if shouldPlayContent
              m.videoPlayer.visible = true
              m.videoPlayer.setFocus(true)
              m.videoPlayer.control = "play"
              m.videoPlayer.observeField("state", "OnVideoPlayerStateChange")
          end if
      end if
  End Sub
  </code></pre>
  
  <p>When I run this I get an error:</p>
  
  <pre><code>Roku_Ads Framework version 1.8
  BRIGHTSCRIPT: ERROR: roAppInfo: class PLUGIN|MARKUP on thread RENDER: roku_ads_lib:/Roku_Ads.brs(527)
  'Dot' Operator attempted with invalid BrightScript Component or interface reference. (runtime error &amp;hec) in roku_ads_lib:/Roku_Ads.brs(528)
  528: ??
  Backtrace:
  #4  Function roku_ads_util_getappid(key_ As String) As String
     file/line: roku_ads_lib:/Roku_Ads.brs(528)
  #3  Function roku_ads_checkallowedfeature(keytype_ As String, util_ As Object) As Boolean
     file/line: roku_ads_lib:/Roku_Ads.brs(1287)
  #2  Function roku_ads_constructor() As Object
     file/line: roku_ads_lib:/Roku_Ads.brs(264)
  #1  Function roku_ads() As Object
     file/line: roku_ads_lib:/Roku_Ads.brs(32)
  #0  Function onitemselected() As Void
     file/line: pkg:/components/screens/DetailsScreen/DetailsScreen.brs(75)
  </code></pre>
  
  <p>What am I doing wrong here?  Can you not play an ad when a method is called from a <code>onChange="onItemSelected"</code> in the component.xml?</p>
  
  <p><strong>Update</strong>: Eugene's <a href="https://stackoverflow.com/a/40546789/563420">answer below</a> is correct, Here is how I solved the problem:</p>
  
  <p>Read about <a href="https://sdkdocs.roku.com/display/sdkdoc/Scene+Graph+Threads" rel="nofollow noreferrer">scene graph threads</a>, <a href="https://sdkdocs.roku.com/display/sdkdoc/Event+Loops" rel="nofollow noreferrer">events</a> and <a href="https://sdkdocs.roku.com/display/sdkdoc/Handling+Application+Events" rel="nofollow noreferrer">handling application events</a>.  Once that is done read <a href="https://forums.roku.com/viewtopic.php?f=34&amp;t=92613&amp;p=543771#p543771" rel="nofollow noreferrer">this post</a> on passing data between the Render thread and main thread.  You will need to understand <a href="https://sdkdocs.roku.com/display/sdkdoc/Scene+Graph+Data+Scoping" rel="nofollow noreferrer">scene graph data scoping</a>.</p>
  
  <p>Essentially you observe the <code>itemSelected</code> field in <code>components/screens/DetailsScreen/DetailsScreen.xml</code>:</p>
  
  <pre><code>m.DetailsScreen = scene.findNode("DetailsScreen")
  m.DetailsScreen.observeField("itemSelected", m.port)
  </code></pre>
  
  <p>Then in your main threads event loop you handle the <code>roSGNodeEvent</code>:</p>
  
  <pre><code>while true
      msg = wait(0, m.port)        
      msgType = type(msg)
  
      ? "&gt;&gt;&gt;Main Thread Msg: ";msgType
  
      if msgType = "roSGScreenEvent"
          if msg.isScreenClosed() then return
      else if msgType = "roSGNodeEvent"
          fieldName = msg.getField()
          fieldData = msg.getData()
          ? "&gt; node: "; msg.getNode()
          ? "&gt; field name: "; fieldName
          ? "&gt; data: "; fieldData
  
          if (fieldName = "itemSelected" and fieldData = 0)   'User pressed play
              'wait for 0.5 second before proceeding to RAF
              sleep(500)
              PlayAd()
          endif
      end if
  end while
  </code></pre>
  
  <p><code>PlayAd()</code> sets <code>m.DetailsScreen.videoPlayerVisible = true</code> IF there was no ad or if ad finished playing.  This causes <code>onVideoVisibleChange</code> to be invoked in <code>components/screens/DetailsScreen/DetailsScreen.brs</code></p>