Forum Discussion

zuber's avatar
zuber
Visitor
11 years ago

secured m3u8 can't play with Roku but with VLC

Why Roku doesn't support secured m3u8 link? I am able to play this in VLC fine.
example...
http://*****_*********_hl-lh.akamaihd.net/i/**_****_hls_1@175738/master.m3u8?hdnea=st=1410478550~exp=1410514550~acl=/*~hmac=7ed6be672a3df528f55369b0b90b076736cce98cd2d886592f6f69133352507f&play-only=backup&jwstreamtype=hls

12 Replies

  • See http://sdkdocs.roku.com/display/sdkdoc/ ... deasString for a useful utility function and a list of the characters you should be concerned about. Inside xml element content or attribute value, they should be escaped to so-called "character entity references".

    BrightScript Debugger> ? "escaped chars: < ' & >".getEntityEncode()
    escaped chars: &lt; &apos; &amp; &gt;
  • Not all video streams that can play on VLC or other media players are able to play on Roku devices. To make sure the stream is Roku-compatible, try running it using this code, which will play a single video and generate debug logs for any errors and system log messages to help you diagnose if/why it won't play. Substitute your video url for the one in this sample code.


    Function _DEBUG_ON () As Boolean : Return True : End Function ' Return True => Debugging ON

    Sub Main ()
    port = CreateObject ("roMessagePort")

    ' Use roSystemLog to log system events
    sl = CreateObject ("roSystemLog")
    sl.SetMessagePort (port)
    sl.EnableType ("http.error")
    sl.EnableType ("http.connect")
    sl.EnableType ("bandwidth.minute")

    ' Use roVideoScreen to play the video
    ui = CreateObject ("roVideoScreen")
    ui.SetMessagePort (port)
    ui.SetCertificatesFile ("common:/certs/ca-bundle.crt") ' Required for "https" urls
    ui.SetContent ({
    StreamFormat: "hls", ' "hls or "mp4"
    Stream: {
    Url: "http://iphone-streaming.ustream.tv/ustreamVideo/1524/streams/live/playlist.m3u8"
    Bitrate: 0
    Quality: False ' At least one SD stream is required if using an SD TV
    }
    })
    ui.Show ()

    ' Event loop
    While True
    msg = Wait (0, port)
    _logEvent ("Main", msg)
    End While

    End Sub

    '
    ' Log events
    '
    Function _logEvent (proc As String, msg As Dynamic) As Void
    If _DEBUG_ON ()
    If msg = Invalid
    evType = "Invalid"
    _debug (proc + ". Invalid")
    Else
    evStr = ""
    evType = Type (msg)
    If evType = "roVideoScreenEvent" Or evType = "roVideoPlayerEvent"
    msgType = msg.GetType ().ToStr ()
    If msg.IsStreamStarted ()
    info = msg.GetInfo ()
    If info.IsUnderrun Then underrun = "true" Else underrun = "false"
    evStr = "isStreamStarted. Index: " + msg.GetIndex ().ToStr ()
    evStr = evStr + ". Url: " + info.Url
    evStr = evStr + ". StreamBitrate: " + StrI (info.StreamBitrate / 1000).Trim ()
    evStr = evStr + ". MeasuredBitrate: " + info.MeasuredBitrate.ToStr ()
    evStr = evStr + ". IsUnderrun: " + underrun
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsPlaybackPosition ()
    evStr = "isPlaybackPosition. Index: " + msg.GetIndex ().ToStr ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsRequestFailed ()
    index = msg.GetIndex ()
    info = msg.GetInfo ()
    evStr = "isRequestFailed. Message: " + msg.GetMessage () + " Index: " + index.ToStr ()
    If index <= 0 And index >= -5
    failMessage = [ "Network error : server down or unresponsive, server is unreachable, network setup problem on the client",
    "HTTP error: malformed headers or HTTP error result",
    "Connection timed out",
    "Unknown error",
    "Empty list; no streams were specified to play",
    "Media error; the media format is unknown or unsupported" ][-index]
    evStr = evStr + " [" + failMessage + "]"
    End If
    If info.LookupCI ("Url") <> Invalid Then evStr = evStr + ". Url: " + info.Url
    If info.LookupCI ("StreamBitrate") <> Invalid Then evStr = evStr + ". StreamBitrate: " + info.StreamBitrate.ToStr ()
    If info.LookupCI ("MeasuredBitrate") <> Invalid Then evStr = evStr + ". MeasuredBitrate: " + info.MeasuredBitrate.ToStr ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsStatusMessage ()
    evStr = "isStatusMessage. Message: " + msg.GetMessage ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsFullResult ()
    evStr = "isFullResult"
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsPartialResult ()
    evStr = "isPartialResult"
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsPaused ()
    evStr = "isPaused"
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsResumed ()
    evStr = "isResumed"
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsScreenClosed ()
    evStr = "isScreenClosed"
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else If msg.IsStreamSegmentInfo ()
    info = msg.GetInfo ()
    evStr = "isStreamSegmentInfo. Message: " + msg.GetMessage () + ". Index: " + msg.GetIndex ().ToStr ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    _debug ("StreamBandwidth: " + info.StreamBandwidth.ToStr (), "> ")
    _debug ("Sequence: " + info.Sequence.ToStr (), "> ")
    _debug ("SegUrl: " + info.SegUrl, "> ")
    _debug ("SegStartTime: " + info.SegStartTime.ToStr (), "> ")
    Else If msg.IsDownloadSegmentInfo () ' Undocumented event
    info = msg.GetInfo ()
    evStr = "isDownloadSegmentInfo. Message: " + msg.GetMessage () + ". Index: " + msg.GetIndex ().ToStr ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    _debug ("Sequence: " + info.Sequence.ToStr (), "> ")
    _debug ("Status: " + info.Status.ToStr (), "> ")
    _debug ("SegBitrate: " + info.SegBitrate.ToStr (), "> ")
    _debug ("DownloadDuration: " + info.DownloadDuration.ToStr (), "> ")
    _debug ("SegUrl: " + info.SegUrl, "> ")
    _debug ("SegSize: " + info.SegSize.ToStr (), "> ")
    _debug ("BufferSize: " + info.BufferSize.ToStr (), "> ")
    _debug ("BufferLevel: " + info.BufferLevel.ToStr (), "> ")
    _debug ("SegType: " + info.SegType.ToStr (), "> ")
    Else If msg.IsListItemSelected () ' Undocumented event for this event type
    evStr = "isListItemSelected ???. Index: " + msg.GetIndex ().ToStr ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    Else
    evStr = "Unknown. Message: " + msg.GetMessage () + " Index: " + msg.GetIndex ().ToStr ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + evStr)
    End If
    Else If evType = "roSystemLogEvent"
    msgType = msg.GetType ().ToStr ()
    info = msg.GetInfo ()
    _debug (proc + ". " + evType + " [" + msgType + "]-" + "LogType=" + info.LogType + ". Datetime: " + _timeStr (info.Datetime))
    evStr = ""
    If info.LogType = "http.error" Or info.LogType = "http.connect"
    _debug ("Url: " + info.Url, "> ")
    _debug ("Status: " + info.Status, "> ")
    _debug ("HttpCode: " + info.HttpCode.ToStr (), "> ")
    _debug ("Method: " + info.Method, "> ")
    _debug ("TargetIp: " + info.TargetIp, "> ")
    _debug ("OrigUrl: " + info.OrigUrl, "> ")
    Else If info.LogType = "bandwidth.minute"
    _debug ("Bandwidth: " + info.bandwidth.ToStr (), "> ")
    Else
    ' Unknown log type
    _debug ("(unknown log type)", "> ")
    End If
    '
    ' Add more event types here as needed ...
    '

    Else
    _debug (proc + ". Unexpected Event: " + evType)
    End If
    End If
    End If
    End Function

    Function _timeStr (dtIn = Invalid As Object) As String

    dt = CreateObject ("roDateTime")

    If dtIn = Invalid
    dt.Mark ()
    Else
    dt = dtIn
    End If

    dt.ToLocalTime ()

    str = ""
    str = str + Right ("0" + dt.GetHours ().ToStr (), 2) + ":"
    str = str + Right ("0" + dt.GetMinutes ().ToStr (), 2) + ":"
    str = str + Right ("0" + dt.GetSeconds ().ToStr (), 2) + "."
    str = str + Right ("00" + dt.GetMilliseconds ().ToStr (), 3) + " "

    Return str

    End Function

    '
    ' Log _debug messages to the console. See _DEBUG () at the start of the code
    '
    Sub _debug (message As String, indentString = "" As String)
    If _DEBUG_ON ()
    dt = CreateObject ("roDateTime")
    dt.ToLocalTime ()
    hh = Right ("0" + dt.GetHours ().ToStr (), 2)
    mm = Right ("0" + dt.GetMinutes ().ToStr (), 2)
    ss = Right ("0" + dt.GetSeconds ().ToStr (), 2)
    mmm = Right ("00" + dt.GetMilliseconds ().ToStr (), 3)
    Print hh; ":"; mm; ":"; ss; "."; mmm; " "; indentString; message
    End If
    End Sub