content: '*
  '* A wrapper around a video player that implements our screen interface.
  '*
  
  '** Credit: Plex Roku https://github.com/plexinc/roku-client-public
  
  '**********************************************************
  '** getPlayConfiguration
  '**********************************************************
  
  Function getPlayConfiguration(context, contextIndex, playOptions) 
  
      list = []
  	
  	initialItem = context[contextIndex]
  	initialItem.PlayOptions = playOptions
  	
      if playOptions.PlayStart = 0 and playOptions.intros <> false
  
          intros = getVideoIntros(initialItem.Id)
  		'intros = getLocalTrailers(initialItem.Id)
  		
          if intros <> invalid
  		
  		for each i in intros.Items		
  			i.PlayOptions = {}
  			list.push(i)
  		end for
  			
  	end if
  
      end if
  
  	currentIndex = 0
  	for each i in context	
  		if currentIndex >= contextIndex then list.push(i)		
  		currentIndex = currentIndex + 1
  	end for
  	
          additional = getAdditionalParts(initialItem.Id)
  
          if additional <> invalid
  		
  		for each i in additional.Items		
  			i.PlayOptions = {}
  			list.push(i)
  		end for
  			
  	end if
  
  	return {
  		Context: list
  		CurIndex: 0
  	}
  	
  End Function
  
  Function createVideoPlayerScreen(context, contextIndex, playOptions, viewController)
  
  	obj = CreateObject("roAssociativeArray")
      initBaseScreen(obj, viewController)
  
  	playConfig = getPlayConfiguration(context, contextIndex, playOptions)
  	
      obj.Context = playConfig.Context
      obj.CurIndex = playConfig.CurIndex
  
      obj.Show = videoPlayerShow
      obj.HandleMessage = videoPlayerHandleMessage
      obj.OnTimerExpired = videoPlayerOnTimerExpired
  
      obj.CreateVideoPlayer = videoPlayerCreateVideoPlayer
  
  	obj.StartTranscodeSessionRequest = videoPlayerStartTranscodeSessionRequest
  	obj.OnUrlEvent = videoPlayerOnUrlEvent
  
      obj.pingTimer = invalid
      obj.lastPosition = 0
  	obj.isPlayed = false
      obj.playbackError = false
  	obj.changeStream = false
      obj.underrunCount = 0
      obj.timelineTimer = invalid
      obj.progressTimer = invalid
      obj.playState = "buffering"
      obj.bufferingTimer = createTimer()
  	obj.LastProgressReportTime = 0
  
      obj.ShowPlaybackError = videoPlayerShowPlaybackError
      obj.UpdateNowPlaying = videoPlayerUpdateNowPlaying
  
      obj.Pause = videoPlayerPause
      obj.Resume = videoPlayerResume
      obj.Next = videoPlayerNext
      obj.Prev = videoPlayerPrev
      obj.Stop = videoPlayerStop
      obj.Seek = videoPlayerSeek
  	obj.SetAudioStreamIndex = videoPlayerSetAudioStreamIndex
  	obj.SetSubtitleStreamIndex = videoPlayerSetSubtitleStreamIndex
  
  	obj.ReportPlayback = videoPlayerReportPlayback
  
  	obj.ConstructVideoItem = videoPlayerConstructVideoItem
  	obj.StopTranscoding = videoPlayerStopTranscoding
  
      return obj
  End Function
  
  Function VideoPlayer()
      ' If the active screen is a slideshow, return it. Otherwise, invalid.
      screen = GetViewController().screens.Peek()
      if type(screen.Screen) = "roVideoScreen" then
          return screen
      else
          return invalid
      end if
  End Function
  
  Sub videoPlayerShow()
      ' We only fall back automatically if we originally tried to Direct Play
      ' and the preference allows fallback. One potential quirk is that we do
      ' fall back if there was progress on the Direct Play attempt. This should
      ' be quite uncommon, but if something happens part way through the file
      ' that the device can't handle, we at least give transcoding (from there)
      ' a shot.
  
      if m.playbackError then
  	createDialog("Playback Error!", "Error while playing video, nothing left to fall back to.", "OK", true)
          Debug("Error while playing video, nothing left to fall back to")
          m.ShowPlaybackError("")
          m.Screen = invalid
          m.popOnActivate = true
  
  	else
  		item = m.Context[m.CurIndex]
  		
  		m.PlayOptions = item.PlayOptions
  		
  		if m.PlayOptions = invalid
  		    m.PlayOptions = {}
  		end if	
  		
          m.Screen = m.CreateVideoPlayer(item, m.PlayOptions)
  		
      end if
  
  	m.changeStream = false
  	
      if m.Screen <> invalid then
  	
          if m.IsTranscoded then
              Debug("Starting to play transcoded video")
          else
              Debug("Starting to direct play video")
          end if
  		
  		Debug("Playback url: " + m.VideoItem.Stream.Url)
  
          m.timelineTimer = createTimer()
          m.timelineTimer.Name = "timeline"
          m.timelineTimer.SetDuration(15000, true)
          m.ViewController.AddTimer(m.timelineTimer, m)
  
          m.progressTimer = createTimer()
          m.progressTimer.Name = "progress"
          m.progressTimer.SetDuration(2000, true)
  		m.progressTimer.Active = false
          m.ViewController.AddTimer(m.progressTimer, m)
  		
          m.Screen.Show()
          NowPlayingManager().location = "fullScreenVideo"
      else
          m.ViewController.PopScreen(m)
          NowPlayingManager().location = "navigation"
      end if
  End Sub
  
  Function videoPlayerCreateVideoPlayer(item, playOptions)
  
      Debug("MediaPlayer::playVideo: Displaying video: " + tostr(item.title))
  
  	if item.IsPlaceHolder = true then
  		m.ShowPlaybackError("PlaceHolder")
  		return invalid
  	end if
  	
      videoItem = m.ConstructVideoItem(item, playOptions)
  
  	if videoItem = invalid or videoItem.Stream = invalid then
  		createDialog("Playback Error!", "No videoItem or VideoItem.Stream found. (invalid)", "OK", true)
  		return invalid
  	end if
  
      player = CreateObject("roVideoScreen")
      player.SetMessagePort(m.Port)
  
      player.SetPositionNotificationPeriod(1)
  
  	' Reset these
  	m.isPlayed = false
      m.lastPosition = 0
      m.playbackError = false
  	m.changeStream = false
      m.underrunCount = 0
      m.timelineTimer = invalid
      m.progressTimer = invalid
      m.playState = "buffering"
      
  	m.IsTranscoded = videoItem.StreamInfo.PlayMethod = "Transcode"
      m.videoItem = videoItem
  
  	if m.IsTranscoded then
  		m.playMethod = "Transcode"	
  	else
  		addBifInfo(videoItem)
  		m.playMethod = "DirectStream"
  	end if
  	
  	m.canSeek = videoItem.StreamInfo.CanSeek
  	
  	Debug ("Setting PlayStart to " + tostr(playOptions.PlayStart))
  	videoItem.PlayStart = playOptions.PlayStart
  
  	if Instr(0, videoItem.Stream.Url, "https:") <> 0 then 
  		player.setCertificatesFile("common:/certs/ca-bundle.crt")
  	end if
  	
  	player.SetContent(videoItem)
  
  	versionArr = getGlobalVar("rokuVersion")
  	
      if CheckMinimumVersion(versionArr, [4, 9]) AND videoItem.SubtitleUrl <> invalid then
          player.ShowSubtitle(true)
      end if
  	
  	return player
  End Function
  
  Sub addBifInfo(item)
  	
  	itemId = item.Id
  	mediaSourceId = item.StreamInfo.MediaSource.Id
  	
  	if IsBifServiceAvailable(item) = true then
  		item.HDBifUrl = GetServerBaseUrl() + "/Videos/" + itemId + "/index.bif?width=320&mediaSourceId=" + mediaSourceId
  		item.SDBifUrl = GetServerBaseUrl() + "/Videos/" + itemId + "/index.bif?width=240&mediaSourceId=" + mediaSourceId
  	end if
  		
  End Sub
  
  Function IsBifServiceAvailable(item)
  
  	if item.ServerId = invalid then
  		return false
  	end if
  	
  	viewController = GetViewController()
  	
  	if viewController.serverPlugins = invalid then
  		viewController.serverPlugins = CreateObject("roAssociativeArray")
  	end if
  	
  	if viewController.serverPlugins[item.ServerId] = invalid then
  		viewController.serverPlugins[item.ServerId] = getInstalledPlugins()
  	end if
  	
  	if viewController.serverPlugins[item.ServerId] <> invalid then
  		for each serverPlugin in viewController.serverPlugins[item.ServerId]
  			if serverPlugin.Name = "Roku Thumbnails" then
  				return true
  			end if
  		end for
  	end if
  	
  	return false
  	
  End Function
  
  Sub videoPlayerShowPlaybackError(code)
      dialog = createBaseDialog()
  
      dialog.Title = "Video Unavailable"
  	
  	if code = "PlaceHolder" then
  		dialog.Text = "The content chosen is not playable from this device."
  	else
  		dialog.Text = "We're unable to play this video, make sure the server is running and has access to this video."
  	end if
  	
      dialog.Show()
  End Sub
  
  Function videoPlayerHandleMessage(msg) As Boolean
  
      handled = false
  
      if type(msg) = "roVideoScreenEvent" then
  
          handled = true
  
          if msg.isScreenClosed() then
  
              m.timelineTimer.Active = false
              m.progressTimer.Active = false
              m.playState = "stopped"
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isScreenClosed: position -> " + tostr(m.lastPosition))
  	    if m.lastPosition = 0
  			t = FirstOf(regRead("prefPlayMethod"),"Auto")
  			if t = "DirectPlay" then
  				createDialog("Playback Error!", "The Video Player has closed prematurely. Your play method is Force DirectPlay. Forcing DirectPlay is NOT supported on the roku at this time."+chr(10)+chr(10)+"Change your play method to FORCE DIRECTSTREAM or one of the USE AUTO DETECTION choices. Sorry."+chr(10), "OK", true)
  			else if left(t,4) = "Auto" then
  				createDialog("Playback Error!", "The Video Player has closed prematurely. Your play method is Use Auto Detection. This error can be caused by a corrupt video stream, or a corrupt item in your library."+chr(10)+chr(10)+"If you are sure the item is not corrupt then please report this video on emby forums so that we can help diagnose your playback error. Thank you and apologies for the issue."+chr(10), "OK", true)
  			else if t = "DirectStream" then
  				createDialog("Playback Error!", "The Video Player has closed prematurely. Your play method is Force DirectStream. Change the play method to one of the USE AUTO DETECTION choices and try again."+chr(10), "OK", true)
  			else
  				createDialog("Playback Error!", "The Video Player has closed prematurely. Your play method is Force Transcoding. Change the play method to one of the USE AUTO DETECTION choices and try again."+chr(10), "OK", true)
  			end if
  	    end if
              NowPlayingManager().location = "navigation"
  
  			m.ReportPlayback("stop")
              m.UpdateNowPlaying()
  
              if m.isPlayed = true AND m.Context.Count() > (m.CurIndex + 1) then
  				m.CurIndex = m.CurIndex + 1
                  m.Show()
              else if m.changeStream
  				m.changeStream = false
                  m.Show()
              else
                  m.ViewController.PopScreen(m)
              end if
  
          else if msg.isStatusMessage() then
              print "Video status: "; msg.GetIndex(); " " msg.GetData()
  
          else if msg.isButtonPressed()
              print "Button pressed: "; msg.GetIndex(); " " msg.GetData()
  
          else if msg.isStreamStarted() then
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isStreamStarted: position -> " + tostr(m.lastPosition))
              Debug("Message data -> " + tostr(msg.GetInfo()))
  
              if msg.GetInfo().IsUnderrun = true then
                  m.underrunCount = m.underrunCount + 1
                  if m.underrunCount = 4 then
                      Debug ("Video is underrun")
                  end if
              end if
  
  			m.ReportPlayback("start")
  
  			m.StartTranscodeSessionRequest()
  
          else if msg.isPlaybackPosition() then
  
              if m.bufferingTimer <> invalid then
                  m.bufferingTimer = invalid
              end if
  
              m.lastPosition = msg.GetIndex()
  
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isPlaybackPosition: set progress -> " + tostr(m.lastPosition))
  
              m.playState = "playing"
  			m.progressTimer.Active = true
  			m.ReportPlayback("progress")
              m.UpdateNowPlaying(true)
  
          else if msg.isRequestFailed() then
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isRequestFailed - message = " + tostr(msg.GetMessage()))
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isRequestFailed - data = " + tostr(msg.GetData()))
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isRequestFailed - index = " + tostr(msg.GetIndex()))
              m.playbackError = true
  
          else if msg.isPaused() then
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isPaused: position -> " + tostr(m.lastPosition))
              m.playState = "paused"
  			m.progressTimer.Active = true
  			m.ReportPlayback("progress", true)
              m.UpdateNowPlaying("progress")
  
          else if msg.isResumed() then
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isResumed")
              m.playState = "playing"
  			m.progressTimer.Active = true
  			m.ReportPlayback("progress", true)
              m.UpdateNowPlaying()
  
          else if msg.isPartialResult() then
  		
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isPartialResult: position -> " + tostr(m.lastPosition))
  			
  			m.progressTimer.Active = false
  			
  			if m.changeStream = false then 
  				m.playState = "stopped"
  				m.ReportPlayback("stop")
  				m.UpdateNowPlaying()
  			else
  				if m.IsTranscoded then m.StopTranscoding()
  			end if
  
          else if msg.isStreamSegmentInfo() then
              Debug("HLS Segment info: " + tostr(msg.GetType()) + " msg: " + tostr(msg.GetMessage()))
  
          else if msg.isFullResult() then
              Debug("MediaPlayer::playVideo::VideoScreenEvent::isFullResult: position -> " + tostr(m.lastPosition))
              m.progressTimer.Active = false
  			m.playState = "stopped"
  			m.ReportPlayback("stop")
              m.UpdateNowPlaying()
  			m.isPlayed = true
  
          else if msg.GetType() = 31 then
              ' TODO(schuyler): DownloadDuration is completely incomprehensible to me.
              ' It doesn't seem like it could be seconds or milliseconds, and I couldn't
              ' seem to do anything to artificially affect it by tweaking PMS.
              segInfo = msg.GetInfo()
              Debug("Downloaded segment " + tostr(segInfo.Sequence) + " in " + tostr(segInfo.DownloadDuration) + "?s (" + tostr(segInfo.SegSize) + " bytes, buffer is now " + tostr(segInfo.BufferLevel) + "/" + tostr(segInfo.BufferSize))
  
          else if msg.GetType() = 27 then
              ' This is an HLS Segment Info event. We don't really need to do
              ' anything with it. It includes info like the stream bandwidth,
              ' sequence, URL, and start time.
  			Debug("HLS Segment info: " + tostr(msg.GetType()) + " msg: " + tostr(msg.GetMessage()))
          else
              'Debug("Unknown event: " + tostr(msg.GetType()) + " msg: " + tostr(msg.GetMessage()))
          end if
      end if
  
      return handled
  End Function
  
  Sub videoPlayerReportPlayback(action as String, forceReport = false)
  
  	m.progressTimer.Mark()
  
  	isPaused = false
  
  	if m.playState = "paused" then 
  		isPaused = true
  	end if
  	
  	position = m.lastPosition
  	playOptions = m.PlayOptions	
  	
  	nowSeconds = CreateObject("roDateTime").AsSeconds()
  	
  	if action = "progress" and forceReport = false then
  		secondsSinceLastProgressReport = nowSeconds - m.LastProgressReportTime
  		
  		if secondsSinceLastProgressReport < 3
  			Debug ("Skipping progress report")
  			return
  		end if
  		
  	end if
  
  	m.LastProgressReportTime = nowSeconds
  	reportPlayback(m.videoItem.Id, "Video", action, m.playMethod, isPaused, m.canSeek, position, m.videoItem.StreamInfo.MediaSource.Id, m.videoItem.StreamInfo.PlaySessionId, m.videoItem.StreamInfo.LiveStreamId, m.videoItem.StreamInfo.AudioStreamIndex, m.videoItem.StreamInfo.SubtitleStreamIndex)
  	
  End Sub
  
  Sub videoPlayerPause()
      if m.Screen <> invalid then
          m.Screen.Pause()
      end if
  End Sub
  
  Sub videoPlayerResume()
      if m.Screen <> invalid then
          m.Screen.Resume()
      end if
  End Sub
  
  Sub videoPlayerNext()
  End Sub
  
  Sub videoPlayerPrev()
  End Sub
  
  Sub videoPlayerSetAudioStreamIndex(index)
      if m.Screen <> invalid then
          
  		item = m.Context[m.CurIndex]
  		item.PlayOptions.AudioStreamIndex = index
  		
  		position = m.lastPosition
  		playOptions = m.PlayOptions	
  
  		item.PlayOptions.PlayStart = position
  		
  		m.changeStream = true
          m.Screen.Close()
      end if
  End Sub
  
  Sub videoPlayerSetSubtitleStreamIndex(index)
      if m.Screen <> invalid then
  	
  		item = m.Context[m.CurIndex]
  		item.PlayOptions.SubtitleStreamIndex = index
  		
  		position = m.lastPosition
  		playOptions = m.PlayOptions	
  
  		item.PlayOptions.PlayStart = position
  		
  		m.changeStream = true
          m.Screen.Close()
      end if
  End Sub
  
  Sub videoPlayerStop()
      if m.Screen <> invalid then
          m.Screen.Close()
      end if
  End Sub
  
  Sub videoPlayerSeek(offset, relative=false)
  
      if m.Screen <> invalid then
  
          if relative then
              offset = offset + (1000 * m.lastPosition)
              if offset < 0 then offset = 0
          end if
  
          if m.playState = "paused" then
              m.Screen.Resume()
              m.Screen.Seek(offset)
          else
              m.Screen.Seek(offset)
          end if
      end if
  
  End Sub
  
  Sub videoPlayerStartTranscodeSessionRequest()
  
      if m.IsTranscoded then
  
          context = CreateObject("roAssociativeArray")
          context.requestType = "transcode"
  
  		request = HttpRequest(GetServerBaseUrl() + "/Sessions?deviceId=" + getGlobalVar("rokuUniqueId", "Unknown"))
  		request.AddAuthorization()
  		request.ContentType("json")
  
  		m.ViewController.StartRequest(request.Http, m, context)
  
      end if
  
  End Sub
  
  Sub videoPlayerOnUrlEvent(msg, requestContext)
  
      if requestContext.requestType = "transcode" then
          if msg.GetResponseCode() = 200 then
  
  			response = normalizeJson(msg.GetString())
  
  			sessions     = ParseJSON(response)
  
  			DisplayTranscodingInfo(m.Screen, m.videoItem, sessions)
  		end if
      end if
  
  End Sub
  
  Sub DisplayTranscodingInfo(screen, item, sessions)
  
  	for each i in sessions
  		
  		if i.TranscodingInfo <> invalid then
  
  			transcodingInfo = i.TranscodingInfo
  
  			item.ReleaseDate = item.OrigReleaseDate + "   Transcoded"
  
  			if transcodingInfo.Width <> invalid or transcodingInfo.Height <> invalid or transcodingInfo.AudioChannels <> invalid then
  
  				item.ReleaseDate = item.ReleaseDate + " ("
  
  				if transcodingInfo.Width <> invalid and transcodingInfo.Height <> invalid then  item.ReleaseDate = item.ReleaseDate + tostr(transcodingInfo.Width) + "x" + tostr(transcodingInfo.Height)
  
  				shown = false
  				if item.StreamInfo <> invalid then
  					serverStreamInfo = item.StreamInfo
  	   				audioStream = serverStreamInfo.AudioStream
  					channels = audioStream.Channels
  
  					' stream defined audio channels
         					if channels <> invalid then
            					if channels = 8 then
                 						audioCh = "7.1"
             					else if channels = 6 then
                 						audioCh = "5.1"
             					else
                						audioCh = tostr(channels)
             					end if
  						item.ReleaseDate = item.ReleaseDate + " " + tostr(audioCh) + "ch"
  						shown = true
         					end if
  				end if
  
  				' transcoded audio channels
         				if transcodingInfo.AudioChannels <> invalid then
            				if transcodingInfo.AudioChannels = 8 then
                 					audioCh = "7.1"
             				else if transcodingInfo.AudioChannels = 6 then
                 					audioCh = "5.1"
             				else
                					audioCh = tostr(transcodingInfo.AudioChannels)
             				end if
  					item.ReleaseDate = item.ReleaseDate
  					if shown then
  						item.ReleaseDate = item.ReleaseDate +"->" + tostr(audioCh) + "ch"
  					else
  						item.ReleaseDate = item.ReleaseDate +" " + tostr(audioCh)
  					end if
         				end if
  				item.ReleaseDate = item.ReleaseDate + ")"
  			end if
  
  			item.ReleaseDate = item.ReleaseDate + chr(10)
  
  			item.length = tostr(item.Length)	
  			vc = "?" : ac = "?"
  			if m.Codecs <> invalid
  				r = CreateObject("roRegex","(.*)/(.*)/(.*)","")
  				match = r.match(m.Codecs)
  				if match.count() > 0 then
  					junk = match[1]
  					vc = LCase(match[2])
  					ac = LCase(match[3])
  				end if
  			end if
  
  			if transcodingInfo.VideoCodec <> invalid then item.ReleaseDate = item.ReleaseDate + "    video: " + vc + "->" + tostr(transcodingInfo.VideoCodec)
  			if transcodingInfo.AudioCodec <> invalid then item.ReleaseDate = item.ReleaseDate + "    audio: " + ac + "->" + tostr(transcodingInfo.AudioCodec)
  
  			screen.SetContent(item)
  
  			exit for
  		end if
  
  	end for
  
  End Sub
  
  Sub videoPlayerOnTimerExpired(timer)
      
  	if timer.Name = "timeline"
          m.UpdateNowPlaying(true)
      else if timer.Name = "progress"
          m.ReportPlayback("progress")
      end if
  
  End Sub
  
  Sub videoPlayerUpdateNowPlaying(force=false)
  
      ' Avoid duplicates
      if m.playState = m.lastTimelineState AND NOT force then return
  
      m.lastTimelineState = m.playState
      m.timelineTimer.Mark()
  
  	item = m.Context[m.CurIndex]
  	
      NowPlayingManager().UpdatePlaybackState("video", item, m.playState, m.lastPosition)
  End Sub
  
  Function videoPlayerConstructVideoItem(item, options) as Object
  
  	item = GetFullItemMetadata(item, true, options)
  
      'if mediaItem <> invalid then videoItem.Duration = mediaItem.duration ' set duration - used for EndTime/TimeLeft on HUD  - ljunkie
  
      if item.ReleaseDate = invalid then  item.ReleaseDate = "" ' we never want to display invalid
      item.OrigReleaseDate = item.ReleaseDate
  
  	releaseDate = item.ReleaseDate
  	serverStreamInfo = item.StreamInfo
  
  	if serverStreamInfo.PlayMethod <> "Transcode" then
  
         audioCh = ""
  	   audioStream = serverStreamInfo.AudioStream
  
         if audioStream <> invalid and audioStream.Channels <> invalid then
             if audioStream.Channels = 8 then
                 audioCh = "7.1"
             else if audioStream.Channels = 6 then
                 audioCh = "5.1"
             else
                audioCh = tostr(audioStream.Channels) + "ch"
             end if
         end if
  
  	   audioCodec = ""
  
  	   if audioStream <> invalid then
  		   if (tostr(audioStream.Codec) = "dca") then
         			audioCodec = "DTS"
  		   else
         			audioCodec = tostr(audioStream.Codec)
  		   end if
  	   end if
  
  	   resolution = ""
  	   ' Change the VideoStream.Width to Height, shows 1920p instead of 1080p and 1280p instead of 720p in Direct Play Info
  	   if serverStreamInfo.VideoStream <> invalid and serverStreamInfo.VideoStream.Height <> invalid then resolution = tostr(serverStreamInfo.VideoStream.Height) + "p "
  
          item.ReleaseDate = releaseDate + "   Direct Play (" + resolution + audioCh + " " + audioCodec + " " + tostr(item.StreamFormat) + ")"
  	else
  
          item.ReleaseDate = releaseDate + "   Transcoded"
  	end if
  
  	return item
  
  End Function
  
  Sub videoPlayerStopTranscoding()
  
  	Debug ("Sending message to server to stop transcoding")
  
      ' URL
      url = GetServerBaseUrl() + "/Videos/ActiveEncodings"
  
      ' Prepare Request
      request = HttpRequest(url)
      request.AddAuthorization()
      request.AddParam("DeviceId", getGlobalVar("rokuUniqueId", "Unknown"))
      request.SetRequest("DELETE")
  
      ' Execute Request
      response = request.PostFromStringWithTimeout("", 5)
  
      if response = invalid
  	createDialog("Transcoding Error!", "Error stopping server transcoding.", "OK", true)
          Debug("Error stopping server transcoding")
      end if
  
  End Sub
  