Closed TermeHansen closed 2 years ago
i need two more things: attach here the https://drod22d.akamaized.net/dk/encrypted/none/b4/625ef6edaa5a612268e778b4/00022162620/stream_fmp4/master_manifest.m3u8 file
and provide stacktrace error, you can get it by running this in your ubuntu terminal:
gdb /usr/lib/x86_64-linux-gnu/kodi/kodi.bin
Reading symbols from...
bt full
should display the error stack trace list
I already wrote the link earlier for the master_manifest.m3u8 that I have posted to pastebin as I can not attach .m3u8 files here...
gdb gave this:
[New Thread 0x7fffd67fc700 (LWP 51058)]
--Type <RET> for more, q to quit, c to continue without paging--
Thread 6 "ActiveAE" received signal SIGFPE, Arithmetic exception.
[Switching to Thread 0x7fffd77fe700 (LWP 51017)]
0x000055555703b2f3 in ActiveAE::CActiveAEBufferPool::Create(unsigned int) ()
(gdb) bt full
#0 0x000055555703b2f3 in ActiveAE::CActiveAEBufferPool::Create(unsigned int) ()
No symbol table info available.
#1 0x00005555570342fd in ActiveAE::CActiveAE::Configure(AEAudioFormat*) ()
No symbol table info available.
#2 0x000055555703778f in ActiveAE::CActiveAE::StateMachine(int, Actor::Protocol*, Actor::Message*) ()
No symbol table info available.
#3 0x0000555557038743 in ActiveAE::CActiveAE::Process() ()
No symbol table info available.
#4 0x0000555556609331 in CThread::Action() ()
No symbol table info available.
#5 0x000055555660b565 in ?? ()
No symbol table info available.
#6 0x000055555660c08d in ?? ()
No symbol table info available.
#7 0x00007ffff5e02de4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
No symbol table info available.
#8 0x00007ffff7624609 in start_thread (arg=<optimized out>) at pthread_create.c:477
ret = <optimized out>
pd = <optimized out>
unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140736808871680, -8742103893974472751, 140737488345598,
140737488345599, 140737488345600, 140736808868928, 8742155572215261137, 8742085113886910417},
mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0,
canceltype = 0}}}
not_first_call = 0
#9 0x00007ffff6241163 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
No locals.
and then
(gdb) continue
Continuing.
Couldn't get registers: No such process.
Couldn't get registers: No such process.
(gdb) [Thread 0x7fffd67fc700 (LWP 51058) exited]
[Thread 0x7fff6cff9700 (LWP 51057) exited]
[Thread 0x7fff6d7fa700 (LWP 51056) exited]
[Thread 0x7fff6dffb700 (LWP 51055) exited]
[Thread 0x7fff6e7fc700 (LWP 51054) exited]
[Thread 0x7fff6effd700 (LWP 51053) exited]
[Thread 0x7fff6f7fe700 (LWP 51052) exited]
[Thread 0x7fff6ffff700 (LWP 51051) exited]
[Thread 0x7fff88c49700 (LWP 51046) exited]
[Thread 0x7fff89ffb700 (LWP 51039) exited]
[Thread 0x7fff8a7fc700 (LWP 51038) exited]
[Thread 0x7fff8affd700 (LWP 51037) exited]
[Thread 0x7fff8bfff700 (LWP 51035) exited]
[Thread 0x7fffa0ff9700 (LWP 51034) exited]
[Thread 0x7fffa17fa700 (LWP 51033) exited]
[Thread 0x7fffa1ffb700 (LWP 51032) exited]
[Thread 0x7fffa27fc700 (LWP 51031) exited]
[Thread 0x7fffa2ffd700 (LWP 51030) exited]
[Thread 0x7fffa37fe700 (LWP 51029) exited]
[Thread 0x7fffa3fff700 (LWP 51028) exited]
[Thread 0x7fffb0f0b700 (LWP 51027) exited]
[Thread 0x7fffb2139700 (LWP 51024) exited]
[Thread 0x7fffb3fff700 (LWP 51023) exited]
[Thread 0x7fffd6ffd700 (LWP 51018) exited]
[Thread 0x7fffd77fe700 (LWP 51017) exited]
[Thread 0x7ffff0d70700 (LWP 51015) exited]
[Thread 0x7ffff1571700 (LWP 51013) exited]
[Thread 0x7ffff15750c0 (LWP 51009) exited]
Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.
thank you i have reopened xbmc Issue the bug now seem to be on kodi side, we keep both opened until a maintainer of that code section gives an answer
Do we have a link to the Kodi bug?
I'm seeing reports of lots of playback broken on latest Nexus: https://forum.kodi.tv/showthread.php?tid=358484&pid=3096948#pid3096948
I wonder if this is the same issue?
now looking a bit closer with gdb on a debug build I did of kodi I see
from running the stream with ffmpeg direct from running the stream with ISA
So I now think the problem lies in the information that ISA provides, I will try to debug from ISA side and see if I get smarter. Totally new to debugging kodi and ISA, so any points on where to put breakpoints in ISA will be appreciated :)
@CastagnaIT can you help me where to debug this in the ISA code?
i dont know what you have debugged, without a working stream is difficult to me what say i can suggest to try start debug on these methods of main.cpp:
bool CInputStreamAdaptive::OpenStream(int streamid) void Session::UpdateStream(STREAM& stream)
to take in account that ffmpeg is different
I think I need a bit more help to dig further into this.
With a breakpoint at https://github.com/xbmc/inputstream.adaptive/blob/62f60ff6c8876e48d2b7c0e2b7bc1a14505fc8ea/src/main.cpp#L1095
GetSampleDescription
returns a desc with TYPE_UNKNOWN, m_format = 0
for my mp4 audio container, while for a similar stream that works I get TYPE_MPEG
back as it should.
So what and where is this GetSampleDescription
And how do debug this further?
hmm downloading the mp4 audio data with curl myself, I can see that something is fishy. it's very small and ffprobe
and file
on linux can not help me on with kind of data this is - does it make sense to you @CastagnaIT
https://paste.c-net.org/AusterEpiphany
termo@X250 ~/k/k/build (Matrix)> file audio_128.mp4 (base)
audio_128.mp4: data
termo@X250 ~/k/k/build (Matrix)> ffprobe -v error -show_format -show_streams audio_128.mp4 (base)
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x559b850a3f00] moov atom not found
audio_128.mp4: Invalid data found when processing input
termo@X250 ~/k/k/build (Matrix) [1]> ffmpeg -i audio_128.mp4 (base)
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x559869ac0600] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x559869ac0600] moov atom not found
audio_128.mp4: Invalid data found when processing input
with ffmpeg I am able to download the audio stream from the master.m3u8 (can I with ffmpeg download only the first segment?). When looking at the ffprobe output between the stream that works and the one that doesn't, I see:
failing audio stream
TAG:major_brand=isom
TAG:minor_version=512
TAG:compatible_brands=isomiso2mp41
TAG:encoder=Lavf58.29.100
and for the one that works:
TAG:major_brand=iso5
TAG:minor_version=512
TAG:compatible_brands=iso6mp41iso5dash
TAG:encoder=Hybrik 1.228.25
edit: looking at the output from ffmpeg when it downloaded the audio stream it says:
Stream #0:1(en): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
variant_bitrate : 1394222
comment : English
major_brand : iso5
minor_version : 512
compatible_brands: iso6mp41iso5dash
encoder : Hybrik 1.228.25
so maybe the diff in the final files is only because of ffmpeg processing...
@TermeHansen The audio_128.mp4 that you posted doesn't look to be an mp4 file. In the sub m3u8 file containing these segments, is there AES-128 encryption? If so the first answer here https://stackoverflow.com/questions/16132088/how-to-decrypt-aes-128-encrypted-m3u8-video-files seems to have a quick way for you to get some of the unencrypted fragments
Alternatively, if you're somehow able to mirror/download one of these 'faulty' streams as-is so we can host locally we can join the debugging efforts. What I mean is the master m3u8, sub m3u8s, and segments/keys within. But that's a lot of work for you
EDIT Also can you please attach one of the sub-m3u8 files as an example?
Should have mentioned - the point to getting the segments is you can open them in something like https://gpac.github.io/mp4box.js/test/filereader.html to see all the details of each box
So what and where is this GetSampleDescription And how do debug this further?
this method come from bento4 sources downloaded when you build ISA: https://github.com/axiomatic-systems/Bento4 source is under folder: source/c++/core/
but we apply also other patches to upstream, that you can find in this path: https://github.com/xbmc/inputstream.adaptive/tree/Nexus/depends/common/bento4
@glennguy thks for your pointers. I have tried based on https://gist.github.com/delimitry/053db410f7fdd4e1d6034a0a7fd45d9b to download and decrypt some of the segments, but I don't see something useful in the mp4box.js :(
The problem here is that the key is without IV, and as I read
An EXT-X-KEY tag with a KEYFORMAT of "identity" that does not have an IV attribute indicates that the Media Sequence Number is to be used as the IV when decrypting a Media Segment, by putting its big-endian binary representation into a 16-octet (128-bit) buffer and padding (on the left) with zeros.
I think I have done it correctly :/
import requests
import sys
from Crypto.Cipher import AES
import m3u8
base = "https://drod22d.akamaized.net/dk/encrypted/none/b4/625ef6edaa5a612268e778b4/00022162620/stream_fmp4/"
audio = "19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.m3u8?aka_me_session_id=AAAAAAAAAAC9CYFiAAAAAPcWUmBPMS8F2ndUH72XjvRiD6D%2f79NvIhqU8VapMZP6GD5pzGB69w8nrlS8lSojj+%2fWPug2sX1+&aka_media_format_type=hls"
m = m3u8.load(base + audio)
def decrypt(data, key, iv):
"""Decrypt using AES CBC"""
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)
return decryptor.decrypt(data)
def get_binary(url):
"""Get binary data from URL"""
data = b''
for chunk in requests.get(url, stream=True):
data += chunk
return data
def dump_segments(m):
key = None
if m.keys[0]:
key = get_binary(m.keys[0].uri)
i = 0
for s in m.segments[:5]:
data = get_binary(m.base_uri + s.uri)
if key:
print()
print(i, int(i).to_bytes(16, "big"))
print(s.uri)
decr_data = decrypt(data, key, int(i).to_bytes(16, "big"))
else:
decr_data = data
with open(f'seg_{i}.mp4','wb') as fh:
fh.write(decr_data)
i += 1
the decrypted mp4 audio files: https://paste.c-net.org/JacksonRomance
the raw data (not tried to decrypt) https://paste.c-net.org/PerformsChilly key = b'\xe9p;\xd4\xe7\xf5\x7f\x84\x04\x98*\x8b\x11\xfc\xb1\xe4'
top part of audio m3u8:
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-MAP:URI="19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_pasthr=AAAAAAAAAADHrX9iAAAAAKnmNv+WiZ%2f3qHxHKe02zPoEqLu+jCaXxr2gWuRLZDNo6s0WwhFVyzE589AFUXNwdaxw+2YcCEKc&aka_media_format_type=hls&aka_sign=fXPtK0QnZ6i3G03vdIRDe%2bervsUpvGLyqawy%2bfNPREQ%3d",BYTERANGE="748@0"
#EXT-X-KEY:METHOD=AES-128,URI="https://drod22d.akamaized.net/dk/encrypted/none/b4/625ef6edaa5a612268e778b4/00022162620/stream_fmp4/serve.key?aka_me_session_id=AAAAAAAAAADHrX9iAAAAAKnmNv+WiZ%2f3qHxHKe02zPoEqLu+jCaXxr2gWuRLZDNo6s0WwhFVyzE589AFUXNwdaxw+2YcCEKc"
#EXTINF:10.005333,
19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_session_id=AAAAAAAAAADHrX9iAAAAAKnmNv+WiZ%2f3qHxHKe02zPoEqLu+jCaXxr2gWuRLZDNo6s0WwhFVyzE589AFUXNwdaxw+2YcCEKc&aka_msn=0&aka_hls_version=6&aka_br=bytes=4124-166634&aka_media_format_type=hls
python print output from the script above:
In [3]: dump_segments(m)
0 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_session_id=AAAAAAAAAAC9CYFiAAAAAPcWUmBPMS8F2ndUH72XjvRiD6D%2f79NvIhqU8VapMZP6GD5pzGB69w8nrlS8lSojj+%2fWPug2sX1+&aka_msn=0&aka_hls_version=6&aka_br=bytes=4124-166634&aka_media_format_type=hls
1 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_session_id=AAAAAAAAAAC9CYFiAAAAAPcWUmBPMS8F2ndUH72XjvRiD6D%2f79NvIhqU8VapMZP6GD5pzGB69w8nrlS8lSojj+%2fWPug2sX1+&aka_msn=1&aka_hls_version=6&aka_br=bytes=166635-328661&aka_media_format_type=hls
2 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'
19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_session_id=AAAAAAAAAAC9CYFiAAAAAPcWUmBPMS8F2ndUH72XjvRiD6D%2f79NvIhqU8VapMZP6GD5pzGB69w8nrlS8lSojj+%2fWPug2sX1+&aka_msn=2&aka_hls_version=6&aka_br=bytes=328662-490702&aka_media_format_type=hls
3 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03'
19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_session_id=AAAAAAAAAAC9CYFiAAAAAPcWUmBPMS8F2ndUH72XjvRiD6D%2f79NvIhqU8VapMZP6GD5pzGB69w8nrlS8lSojj+%2fWPug2sX1+&aka_msn=3&aka_hls_version=6&aka_br=bytes=490703-652833&aka_media_format_type=hls
4 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04'
19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_session_id=AAAAAAAAAAC9CYFiAAAAAPcWUmBPMS8F2ndUH72XjvRiD6D%2f79NvIhqU8VapMZP6GD5pzGB69w8nrlS8lSojj+%2fWPug2sX1+&aka_msn=4&aka_hls_version=6&aka_br=bytes=652834-814705&aka_media_format_type=hls
Decrypted files look fine, thanks for that!
What would be very useful is getting the initialization file, the one held here: #EXT-X-MAP:URI="19670288-c1a4b3d4-2f57-4d1e-899d-475356f6b3b9_audio_128kbps.mp4?aka_me_pasthr=AAAAAAAAAADHrX9iAAAAAKnmNv+WiZ%2f3qHxHKe02zPoEqLu+jCaXxr2gWuRLZDNo6s0WwhFVyzE589AFUXNwdaxw+2YcCEKc&aka_media_format_type=hls&aka_sign=fXPtK0QnZ6i3G03vdIRDe%2bervsUpvGLyqawy%2bfNPREQ%3d",BYTERANGE="748@0"
just need bytes 0-748, you can try putting &aka_br=bytes=0-748
at the end of the url for this.
If you omit that parameter you might just get the whole audio file in one piece?
Interesting though that this init segment (according to playlist) isn't encrypted, but still from the same URI (except parameters are different)
Here is the first 748 bytes (init) and dump with no range (all.mp4):
https://paste.c-net.org/ValidityGlobe
with open("init", "wb") as fh:
fh.write(get_binary(base + m.segments[0].uri.replace("4124-166634", "0-748")))
Ok thanks for that.
Looks like 2 problems here:
1:
The init segment is encrypted even though the playlist says it is not:
https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-11#section-4.4.4.4
Any Media Segment or Media Initialization Section that precedes the first EXT-X-KEY tag is unencrypted
Btw, have you tried playing this stream with another player, eg. VLC? - interested to see how that goes. Obviously this particular video works fine with DRNU official player right?
2: Even if that key tag was before the ext-x-map one, IA does not act on it. So I'll work on fixing that now.
Also, strange in your log that it doesn't disable the stream (and probably prevent the crashing). I'm testing on my end by using that init segment for a playlist I serve locally. When it tries to read the init segment before creating the FragmentedSampleReader it errors with ERROR <general>: AddOnLog: inputstream.adaptive: No MOOV in stream!
@glennguy sounds awesome. Yes ffmpeg and by that ffmpegdirect in kodi works fine for that stream. Only issue is in general for le with ffmpegdirect that skipping does not work for the hls streams (and slow start).
Sounds great to use this bug also to avoid the hard crash of kodi...
@TermeHansen I've just done up a draft PR to allow for encrypted init segments in Kodi 20 - #985 I know you're on 19 but you'd have to build yourself anyway in Linux. Should be able to cherry pick the commit (only worry about changes to HLSTree.cpp)
On your end however, since the playlist is 'incorrect' or rather broken, you'd have to set up a proxy to run the playlist through to IA to make the modification. Should be fine to just move the EXT-X-KEY line before the EXT-X-MAP one.
Yes ffmpeg and by that ffmpegdirect in kodi works fine for that stream uri.replace("4124-166634", "0-748")))
Did you download the init using the same URI the segments use? If so could you try again using the specific URI provided in EXT-X-MAP? The url parameters are different, and I'm wondering if it comes unencrypted that way. Normally the player would add range headers to get the required range of bytes e.g requests.get(url, headers={"Range": "bytes=0-748"})
so please try that and post the file back here
the init from the correct uri :)
r = requests.get(m.segment_map[0].absolute_uri, headers={"Range": "bytes=0-748"})
with open("init.map", "wb") as fh:
fh.write(r.content)
https://paste.c-net.org/PantingDiners
I think you are right it is not encrypted like this. But if that is the case, then the m3u8 should work correctly with IA as is right? So then back to initial problem, why is the format and sampling rate not set correct for this stream?
from here seem that if BYTERANGE value is found the initialization will be ignored: https://github.com/xbmc/inputstream.adaptive/blob/20.2.0-Nexus/src/parser/HLSTree.cpp#L692-L696 then also the range values are not parsed
from here seem that if BYTERANGE value is found the initialization will be ignored: https://github.com/xbmc/inputstream.adaptive/blob/20.2.0-Nexus/src/parser/HLSTree.cpp#L692-L696 then also the range values are not parsed
That seems very odd, can git blame maybe point in a direction to why that line is there (on mobile right now)
I think you are right it is not encrypted like this
Ok that's good to know :)
@CastagnaIT yes you are right
The init segment is found implicitly by using the start byterange of the first media segment then working backwards. Since there are no EXT-X-BYTERANGE tags for the media segments in this case, the setting of the init segment never happens.
I'll post a solution soon
Ok PR in #986
@CastagnaIT Thanks heaps for steering me towards the real problem
@TermeHansen Are you able to cherry-pick and build the changes on your system to test? Alternatively if you have access to Kodi 20 on Mac/Windows/Android then a build is available here: https://jenkins.kodi.tv/blue/organizations/jenkins/xbmc%2Finputstream.adaptive/detail/PR-986/1/artifacts
https://jenkins.kodi.tv/blue/organizations/jenkins/xbmc%2Finputstream.adaptive/detail/PR-986/2/artifacts
@glennguy I Will cherry pick and check for my addon on kodi stable, and then start the nexus branch of my addon to test also there 🤓
I will report here....
@glennguy tested and works great for this problem - thks! Will you bump to 19.0.5? I use inputstreamhelper in my addon, will that automatically update ISA on my users devices or how does that work?
@glennguy but maybe we should have a check on m_sampleRate never should be set to 0, as it will bring kodi to crash, and instead either drop the stream or have ISA fail and write something to kodi?
although we send missing data kodi itself should not crashes means that in kodi core something is unhandled
Updates are handled by Kodi and the user's settings. I'm not an expert in inputstreamhelper, does it do more than making sure the user has libwidevinecdm?
As far as crashing goes - what @CastagnaIT said. Really though the condition that lead to that has been solved now so it shouldn't be an issue at least in this case.
@TermeHansen Inputstream helper does not update ISA. Kodi should automatically update ISA on most platforms except Linux (they need to manually update the inputstream package outside of Kodi)
Oh, and not uwp (Xbox) . Xbox needs it to be built-in to Kodi itself so that would need to wait till 19.5
Bug report
Describe the bug
When starting playback of some specific streams via the plugin.video.drnu addon, kodi will crash when using the adaptive inputstream. When using the normal ffmpeg demuxer it will play but will crash when trying to skip.
Expected Behavior
Normal playback of hls stream
Actual Behavior
kodi crashes with no errors in debug log
To Reproduce
Play a .strm file with:
master_manifest.m3u8
Debuglog
The debug log can be found here: https://pastebin.com/qPSALQ9v
crashlog https://pastebin.com/fk89XGBc
Additional context
tried with ffmpegdirect. It starts but kodi crash when trying to skip...
Your Environment
Used Operating system:
[ ] Android
[ ] iOS
[ ] tvOS
[X] Linux
[ ] OSX
[ ] Windows
[ ] Windows UWP
Operating system version/name: Ubuntu 20.04
Kodi version: 19.4.0