Skip to content

Live M3U8 stream with widevine encryption is not seekable while it should be #1779

@lostheadset

Description

@lostheadset

Bug Report

Describe the Bug

I've been experimenting with Kodi to determine which video formats are supported, and I'm quite sure the following is either a bug or a missing feature.

I found some M3U8 live streams protected by Widevine encryption that are supposed to be seekable (both backward and forward), but the Kodi player does not allow seeking.

Specifically, this issue occurs with the live streams provided by this plugin:
Add-on: Rai Play

I can confirm that seeking should be possible because I wrote an Android app using ExoPlayer, which can seek these streams without any issues.

Expected Behavior

Pressing left or right should allow seeking within the stream.

Actual Behavior

I cannot seek backward or forward in the stream.

To Reproduce

i butchered the Rai plugin to get a minimal working example that you can try for yourself:

# -*- coding: utf-8 -*-
import sys
import xbmc
import xbmcgui
import xbmcplugin
import urllib
import json
import re

import urllib.request as urllib2
import html.parser as HTMLParser
import urllib.parse as urlparse
from urllib.parse import urlencode

# plugin handle
handle = int(sys.argv[1])

UserAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36&Accept=*/*&Accept-Encoding=gzip,deflate,br&Accept-Language=it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7&Connection=keep-alive&Origin=https://www.raiplay.it&Referer=https://www.raiplay.it/&sec-ch-ua="Not A(Brand";v="99","Google Chrome";v="121","Chromium";v="121"&sec-ch-ua-mobile=?0&sec-ch-ua-platform="Linux"'
def getURL(url):
    opener = urllib2.build_opener()
    opener.addheaders = [('User-Agent', UserAgent)]
    urllib2.install_opener(opener)
    scheme, netloc, path, params, query, fragment = urlparse.urlparse(url)
    qs = urlparse.parse_qs(query)
    qs['output'] = "56" # xml stream data  
    
    query = urlencode(qs, True)
    url = urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
            
    response = urllib2.urlopen(url).read()
    response = response.decode('utf-8')

    content = re.findall("<url type=\"content\">(.*?)</url>", response)
    url = re.findall("<!\[CDATA\[(.*?)\]\]>",content[0]) 
    ct = re.findall("<ct>(.*?)</ct>", response)
    licenseUrl = re.findall("<license_url>(.*?)</license_url>", response) 
    licenseJson = re.findall("<!\[CDATA\[(.*?)\]\]>",licenseUrl[0])
    licenseJson = json.loads(licenseJson[0])
    licenseData = licenseJson.get('drmLicenseUrlValues',[])
    key = ''  
    for l in licenseData:
        if "WIDEVINE" in l.get("drm",""):
            key = l.get("licenceUrl",'')

    return {'url': url[0],'ct': ct[0],'key': key}

def play(url, pathId="", srt=[]):
    
    url = url.replace ("https:", "http:")
    xbmc.log("Relinker URL: " + url)
    url = getURL(url).get('url','')
        
    item=xbmcgui.ListItem(path=url + '|User-Agent=' + urllib.parse.quote_plus(UserAgent))
    item.setProperty('inputstream', 'inputstream.adaptive')
    item.setProperty('inputstream.adaptive.manifest_type', 'mpd')
    item.setMimeType('application/dash+xml')
    item.setProperty('inputstream.adaptive.manifest_type', 'hls')
    xbmcplugin.setResolvedUrl(handle=handle, succeeded=True, listitem=item)

# parameter values
params = dict(urlparse.parse_qsl(sys.argv[2][1:]))
mode = str(params.get("mode", ""))
url = str(params.get("url", ""))
pathId = str(params.get("path_id", ""))

if mode == "play" or mode =="raiplay_videos":
    play("https://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=308718", "")
else:
    liStyle = xbmcgui.ListItem("Video")
    liStyle.setInfo("video", {})
    url = sys.argv[0] + '?' + urlencode({"mode": "play", "url": 'https://mediapolis.rai.it/relinker/relinkerServlet.htm?cont=308718'})
    liStyle.setProperty('IsPlayable', 'true')
    xbmcplugin.addDirectoryItem(handle=handle, url=url, listitem=liStyle, isFolder=False)
    xbmcplugin.endOfDirectory(handle=handle, succeeded=True)

Debuglog

2025-02-16 19:32:34.682 T:5272     info <general>: CIRServerSuite::Process: failed to connect to irss, will keep retrying every 5 seconds
2025-02-16 19:32:40.429 T:19372    info <general>: VideoPlayer::OpenFile: plugin://plugin.video.raitv/?mode=play&url=https%3A%2F%2Fmediapolis.rai.it%2Frelinker%2FrelinkerServlet.htm%3Fcont%3D308718
2025-02-16 19:32:40.624 T:18540    info <general>: Creating InputStream
2025-02-16 19:32:40.625 T:18540 warning <general>: AddOnLog: inputstream.adaptive: Warning "inputstream.adaptive.manifest_type" property is deprecated and will be removed next Kodi version, the manifest type is now automatically detected.
                                                   If you are using a proxy remember to add the appropriate "content-type" header to the HTTP manifest response
                                                   See Wiki page "How to provide custom manifest/license" to learn more about it.
2025-02-16 19:32:40.626 T:18540    info <general>: AddOnLog: inputstream.adaptive: [Repr. chooser] Resolution set: 3416x1310, max allowed: 3416x1310, Adjust refresh rate: 0
2025-02-16 19:32:40.755 T:18540    info <general>: AddOnLog: inputstream.adaptive: Manifest successfully parsed (Periods: 1, Streams in first period: 4, Type: live)
2025-02-16 19:32:40.756 T:18540    info <general>: Creating Demuxer
2025-02-16 19:32:40.756 T:18540    info <general>: Opening stream: 1001 source: 256
2025-02-16 19:32:40.850 T:18540 warning <general>: AddOnLog: inputstream.adaptive: SESSION::CSession::OnSegmentChanged: Cannot get the stream sample reader
2025-02-16 19:32:40.964 T:10744 warning <general>: [WS-Discovery]: The initial search for servers has failed. No servers found.
2025-02-16 19:32:41.027 T:18540    info <general>: Creating video codec with codec id: 27
2025-02-16 19:32:41.027 T:18540    info <general>: CDVDVideoCodecFFmpeg::Open() Using codec: H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
2025-02-16 19:32:41.028 T:18540    info <general>: Creating video thread
2025-02-16 19:32:41.028 T:8876     info <general>: running thread: video_thread
2025-02-16 19:32:41.028 T:18540    info <general>: Opening stream: 1002 source: 256
2025-02-16 19:32:41.069 T:18540 warning <general>: AddOnLog: inputstream.adaptive: SESSION::CSession::OnSegmentChanged: Cannot get the stream sample reader
2025-02-16 19:32:41.152 T:18540    info <general>: Finding audio codec for: 86018
2025-02-16 19:32:41.153 T:18540    info <general>: CDVDAudioCodecFFmpeg::Open() Successful opened audio decoder aac
2025-02-16 19:32:41.153 T:18540    info <general>: CVideoPlayerAudio::OpenStream: Allowing max Out-Of-Sync Value of 50 ms
2025-02-16 19:32:41.153 T:18540    info <general>: Creating audio thread
2025-02-16 19:32:41.153 T:14220    info <general>: running thread: CVideoPlayerAudio::Process()
2025-02-16 19:32:41.154 T:8876     info <general>: DXVA::CContext::CreateContext: creating discrete d3d11va device for decoding.
2025-02-16 19:32:41.164 T:14220    info <general>: CDVDAudioCodecFFmpeg::Open() Successful opened audio decoder aac
2025-02-16 19:32:41.164 T:14220    info <general>: Creating audio stream (codec id: 86018, channels: 2, sample rate: 44100, no pass-through)
2025-02-16 19:32:41.190 T:17536    info <general>: CActiveAESink::OpenSink - initialize sink
2025-02-16 19:32:41.216 T:8876     info <general>: DXVA::CContext::CreateContext: device for decoding created on adapter 'NVIDIA GeForce GTX 1660' with D3D_FEATURE_LEVEL_12_1
2025-02-16 19:32:41.217 T:8876     info <general>: DXVA::CDecoder::Open: Total video memory available is 14121 MB (dedicated = 5966 MB, shared = 8155 MB)
2025-02-16 19:32:41.245 T:8876     info <general>: DXVA::CVideoBufferShared::InitializeFence: fence synchronization activated.
2025-02-16 19:32:41.250 T:19372    info <general>: CRendererDXVA::Configure: chosen conversion: NV12 / YCBCR_STUDIO_G22_LEFT_P709 to R10G10B10A2_UNORM / RGB_FULL_G22_NONE_P709
2025-02-16 19:32:41.250 T:19372    info <general>: DXVA::CEnumeratorHD::ProbeProcessorCaps: supported deinterlace methods: blend:yes, bob:yes, adaptive:yes, mocomp:no.
2025-02-16 19:32:41.250 T:19372 warning <general>: CRendererHQ::CheckVideoParameters: chosen scaling method 1 is not supported by renderer
2025-02-16 19:32:41.251 T:8876     info <general>: DXVA::CVideoBufferShared::InitializeFence: fence synchronization activated.
2025-02-16 19:32:41.266 T:19372    info <general>: Skipped 5 duplicate messages..
2025-02-16 19:32:41.266 T:19372    info <general>: Loading skin file: VideoFullScreen.xml, load type: KEEP_IN_MEMORY
2025-02-16 19:32:41.380 T:19372    info <general>: Loading skin file: VideoOSD.xml, load type: KEEP_IN_MEMORY
2025-02-16 19:32:41.764 T:8876  warning <general>: CVideoPlayerVideo::OutputPicture - timeout waiting for buffer
2025-02-16 19:32:42.299 T:8876     info <general>: CDVDVideoCodecFFmpeg::CDropControl: calculated diff time: 40000
2025-02-16 19:32:42.574 T:19372    info <general>: Stopping the application...
2025-02-16 19:32:42.574 T:19372    info <general>: Stopping player
2025-02-16 19:32:42.574 T:19372    info <general>: CVideoPlayer::CloseFile()
2025-02-16 19:32:42.574 T:19372    info <general>: VideoPlayer: waiting for threads to exit
2025-02-16 19:32:42.575 T:18540    info <general>: CVideoPlayer::OnExit()
2025-02-16 19:32:42.575 T:18540    info <general>: Closing stream player 1
2025-02-16 19:32:42.575 T:18540    info <general>: Waiting for audio thread to exit
2025-02-16 19:32:42.585 T:14220    info <general>: thread end: CVideoPlayerAudio::OnExit()
2025-02-16 19:32:42.585 T:18540    info <general>: Closing audio device
2025-02-16 19:32:42.606 T:18540    info <general>: Deleting audio codec
2025-02-16 19:32:42.606 T:18540    info <general>: Closing stream player 2
2025-02-16 19:32:42.606 T:18540    info <general>: waiting for video thread to exit
2025-02-16 19:32:42.619 T:8876     info <general>: thread end: video_thread
2025-02-16 19:32:42.619 T:18540    info <general>: deleting video codec
2025-02-16 19:32:42.620 T:18540    info <general>: DXVA::CDecoder::Close: closing decoder.
2025-02-16 19:32:42.620 T:18540    info <general>: DXVA: closing decoder context.
2025-02-16 19:32:42.639 T:18540    info <general>: ADDON: Dll Destroyed - InputStream Adaptive
2025-02-16 19:32:42.639 T:19372    info <general>: VideoPlayer: finished waiting
2025-02-16 19:32:42.639 T:4164     info <general>: Deleting settings information for files plugin://plugin.video.raitv/?mode=play&url=https%3A%2F%2Fmediapolis.rai.it%2Frelinker%2FrelinkerServlet.htm%3Fcont%3D308718
2025-02-16 19:32:42.639 T:19372    info <general>: CVideoPlayer::CloseFile()
2025-02-16 19:32:42.639 T:19372    info <general>: VideoPlayer: waiting for threads to exit
2025-02-16 19:32:42.639 T:19372    info <general>: VideoPlayer: finished waiting
2025-02-16 19:32:42.651 T:19372    info <general>: Storing total System Uptime
2025-02-16 19:32:42.651 T:19372    info <general>: Saving settings
2025-02-16 19:32:42.653 T:19372    info <general>: Saving skin settings
2025-02-16 19:32:42.654 T:19372    info <general>: Stopping all

Screenshots

Image
you can clearly see there is no forward or backward button

Your Environment

Used Operating system:
I tested on different platforms and they all present the problem:

  • Android

  • iOS

  • tvOS

  • Linux

  • macOS

  • Windows

  • Windows UWP

  • Kodi version:
    Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    Triage: Needed(managed by bot) issue that was just created and needs someone looking at it

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions