Custom Stream Time Out

Good evening,
I’m trying to develop a timeout functionality much like what you see with Netflix. The basic concept goes that when a live stream is being broadcast, a timer is running in the background and when a predetermined amount of time elapses a confirmation box pops up asking the viewer if they are still watching the stream. I was able to create a working example with a basic channel from scratch only using one static video.

However, when I tried to migrate the timer code into an existing channel we have, based on the videoPlayer example, it breaks. Navigation happens like normal and when a video is selected it starts playing. However, if you click no on the “Still Watching” confirmation box, or if the confirmation times out and goes back to the previous screen from the video, the channel is pretty much stuck. You can go backward in the stack, but can’t select anything that moves you forward. In other words, you can go back all the way to the main screen on the Roku, but you can’t start playing another video or continue playing the video you were just on.

What I did was to take the timer functions that I was using and plug them into the channel and call the timer right after the video starts playing in the appVideoScreen.brs. I also pass the video screen object so that the timer functions would have access to it and be able to close it if need be.

Initially called here from appVideoScreen.brs:


    while true
    	print "Playing Video"
        msg = wait(0, port)

        if type(msg) = "roVideoScreenEvent" then
            print "showHomeScreen | msg = "; msg.getMessage() " | index = "; msg.GetIndex()
            if msg.isfullresult()
            	print "Video Completed Playback Normally"
            	RegDelete(episode.ContentId)
            	print "deleted bookmark for playback position"
            else if msg.isScreenClosed()
                print "Screen closed"
                exit while
            elseif msg.isRequestFailed()
                print "Video request failure: "; msg.GetIndex(); " " msg.GetData()
            elseif msg.isStatusMessage()
                print "Video status: "; msg.GetIndex(); " " msg.GetData()
            elseif msg.isButtonPressed()
                print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
            elseif msg.isPlaybackPosition() then
                nowpos = msg.GetIndex()
                RegWrite(episode.ContentId, nowpos.toStr())
            else
                print "Unexpected event type: "; msg.GetType()
            end if
        else
            print "Unexpected message class: "; type(msg)
        end if
    	Main_Timer(screen)  ' <----------------------- Timer is called here
    end while

The timer functions:


Sub Main_Timer(screen as object)
	timer_bool = 1
	popup_time = 10000
	m.close_time = 10000

	print "Main Timer Started"

    timer_main = createObject("rotimespan")
    port_main_timer = CreateObject("roMessagePort")

    timer_main.Mark()

    while true
		event = port_main_timer.GetMessage()

		if(event = invalid)
			ticks = timer_main.TotalMilliseconds()

			if(ticks > popup_time AND ticks < (popup_time+2000) AND timer_bool = 1)
				print Stri(popup_time+2000)
				response = Show_Popup()
				if (response = true)
					timer_bool = 1
					print "Yes Button Was Pressed"
					timer_main.Mark()
				else if (response = false)
					timer_bool = 0
					print "No Button Was Pressed"
					'END
					m.watching_popup.Close()
					screen.Close()
				end if
			end if
		end if
	end while
End Sub

Function Show_Popup() as Boolean
	print "Starting Popup Function"
	newport = CreateObject("roMessagePort")
    m.watching_popup = CreateObject("roMessageDialog")
    m.watching_popup.SetMessagePort(newport) ' instruct screen to send events to port

	m.watching_popup.SetTitle("Viewer")
    m.watching_popup.SetText("Are you still watching?")

    m.watching_popup.AddButton(0, "Yes")
    m.watching_popup.AddButton(1, "No")

    m.watching_popup.Show()
    print "Popup Shown"

    timer=createObject("rotimespan")
    timer.Mark()

    while true
		msg = wait(m.close_time, m.watching_popup.GetMessagePort())
	    if type(msg) = "roMessageDialogEvent"
	    	if msg.isButtonPressed()
	    		if msg.GetIndex() = 0
	    			print "Popup - Yes pressed"
	    			m.watching_popup.Close()
					return true
	    			exit while
	    		else if msg.GetIndex() = 1
	    			print "Popup - No pressed"
	    			m.watching_popup.Close()
	    			return false
	    			exit while
	    		end if
	    	end if
	    end if
	    return false
	end while

End Function

Now I know that Netflix doesn’t actually go back in the stack like I’m doing here. It just stops the video. So is that what I need to do instead?

You should not have an event loop inside your Main_Timer function. Main_Timer is already being called in every iteration of your main (video processing) event loop. You should create the timer before your main loop starts, not in Main_Timer, and just check the timer in Main_Timer. BTW you may also want to use a nonzero timeout in your wait call, so that the timer code gets called even when no events are occurring.

–Mark