chrippa / livestreamer

Command-line utility that extracts streams from various services and pipes them into a video player of choice. No longer maintained, use streamlink or youtube-dl instead.
http://livestreamer.io/
BSD 2-Clause "Simplified" License
3.88k stars 580 forks source link

bulsat.com plugin request #678

Open teou1 opened 9 years ago

teou1 commented 9 years ago

Hello and greetings from Bulgaria! Bulsatcom is the largest Bulgarian Satellite TV operator, and they are currently testing some form of IPTV. Unfortunatelly, they provide only Android (iOS soon) application for watching this tv, and obviously a lot of people want to watch on their PCs. I digged a lot into the working principle and i think Livestreamer should be able to do the job nicely, but i am not a Phyton programmer and cannot do the plugin myself, so help would be greatly appreciated. Thanks in advance.

Requirements: there are no IP or GeoIP restrictions so far, so you can access and test yourself. There is also a temporary public test user account - user@user.us, pass 1111.

What i can provide: some java code if needed - the first beta versions of the app were not completely obfurscated, that's how i got the betatest user - it was hardcoded :) I have also VLC logs (it works for a couple of minutes and then stops with 403 forbidden, i guess auth cookie is not carried across redirects or refreshes), from which i see that the streaming server is Wowza 4.1 and the format is HLS with 2 streams. I also did some Wireshark sniffing... you see i did everything a non-programmer can but now i am stuck :)

Working principle of the whole thing:

The Android app sends a get request to the server in the form like http://api.iptv.bulsat.com/?auth&device_id=56e3a2175555e674&pass=FW2Ec%2BvkNbvXc%2Bh0tbIHViU3viw%2F1n8zjAhHExdPOm8%3D&user=user%40user.us Device id is the unique Android ID of the device, seems that there is no validation and any fake 16 char value can be there. Pass is the uri-encoded hash of the pass 1111. Looks like base64 encoded sha256 hash, but i cannot be sure - i do not find in the java code where the salt comes from. Let's use it directly as a hash for now. User is the test user - user@user.us, still working but they will stop it eventually.

Next the server responds with a JSON {"Logged":"true"} if the credentials match and sets the auth cookie like SSBULSATAPI=04887985103d28d9986ba42bd558bb1b. After the app sees it is logged, it then requests the JSON channel list with EPG, channel logos, and most importantly, sources - http://api.iptv.bulsat.com/?json&tv&mini . The answer of the server looks like this

{"tv":[{"channel":"101","title":"БНТ 1 HD","logo_mobile":"http:\/\/api.iptv.bulsat.com\/logos\/101-BNT%201%20HD_mobile.png","logo_mobile_selected":"http:\/\/api.iptv.bulsat.com\/logos\/101-BNT%201%20HD_mobile_selected.png","sources":"http:\/\/live1.iptv.bulsat.com:1935\/redirect\/tv\/smil:bnt1_hd_mobile.smil?scheme=m3u8&bulsatCustomParameter=1&bulsatendtime=1421157866&bulsatstarttime=1421149566&bulsathash=sb6oKlQx6-5blCeQCzY9diq7JJyQsQM04u2s-6AJoVk=","pg":"free","program":"Бялата стая 100 години българско кино","desc":"игрален филм повторение","stop":"20150113122500 +0000","start":"20150113110000 +0000"},{"channel"..................

Note that here are some session start/end values and some kind of session hash. I guess this thing should be periodically refreshed and the stream source url with the hash updated.

If i paste the source url in VLC it plays, detects streams, gets redirected, plays the first pieces for a while and than at some point gets kicked from the server with 403 forbidden. I can provide a vlc debug log if needed.

Thank very much in advance, if someone helps! I see there are similar plugins sending fake user agents and remembering cookies and interpreting JSON and playing HLS, so it should be possible to be made.

teou1 commented 9 years ago

p.s. And maybe faking the user-agent to contain "Android" would be a nice idea. Here are some ideas - http://www.useragentstring.com/pages/Android%20Webkit%20Browser/

teou1 commented 9 years ago

A little update: i found the useragent: first in the android application looking for m3u8 is

Apache-HttpClient/UNAVAILABLE (Java 1.4)

and then after all the redirects to the real .TS files with selected quality, the native android player is

stagefright/1.2 (Linux; Android 4.1.2)

The version of Android varying of course.

And a log from VLC - you can see the redirects, streams with hight an low quality and stopping after some time:

main debug: creating access 'http' location='185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6328.ts', path='\\185.4.83.203:1935\tv2m\_definst_\smil:bnt2_mobile.smil\media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6328.ts'
main debug: looking for access module matching "http": 20 candidates
access_http debug: querying proxy for http://185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6328.ts
access_http debug: no proxy
access_http debug: http: server='185.4.83.203' port=1935 file='/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6328.ts'
main debug: net: connecting to 185.4.83.203 port 1935
main debug: connection succeeded (socket = 2804)
access_http debug: protocol 'HTTP' answer code 200
access_http debug: Server: WowzaStreamingEngine/4.1.1
access_http debug: Content-Type: video/MP2T
access_http debug: this frame size=1267120
main debug: using access module "access_http"
main debug: Using stream method for AStream*
main debug: starting pre-buffering
main debug: received first data after 0 ms
main debug: pre-buffering done 1024 bytes in 0s - 1000000 KiB/s
main debug: removing module "access_http"
httplive debug: downloaded segment 6328 from stream 1
httplive debug: candidate 0 bandwidth (bits/s) 43882943 >= 300000
httplive debug: candidate 1 bandwidth (bits/s) 43882943 >= 800000
main debug: creating access 'http' location='185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6329.ts', path='\\185.4.83.203:1935\tv2m\_definst_\smil:bnt2_mobile.smil\media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6329.ts'
main debug: looking for access module matching "http": 20 candidates
access_http debug: querying proxy for http://185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6329.ts
access_http debug: no proxy
access_http debug: http: server='185.4.83.203' port=1935 file='/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6329.ts'
main debug: net: connecting to 185.4.83.203 port 1935
main debug: connection succeeded (socket = 1708)
access_http debug: protocol 'HTTP' answer code 200
access_http debug: Server: WowzaStreamingEngine/4.1.1
access_http debug: Content-Type: video/MP2T
access_http debug: this frame size=846564
main debug: using access module "access_http"
main debug: Using stream method for AStream*
main debug: starting pre-buffering
main debug: received first data after 4 ms
main debug: pre-buffering done 1024 bytes in 0s - 249 KiB/s
main debug: removing module "access_http"
httplive debug: downloaded segment 6329 from stream 1
httplive debug: candidate 0 bandwidth (bits/s) 38480181 >= 300000
httplive debug: candidate 1 bandwidth (bits/s) 38480181 >= 800000
main debug: creating access 'http' location='185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6330.ts', path='\\185.4.83.203:1935\tv2m\_definst_\smil:bnt2_mobile.smil\media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6330.ts'
main debug: looking for access module matching "http": 20 candidates
access_http debug: querying proxy for http://185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6330.ts
access_http debug: no proxy
access_http debug: http: server='185.4.83.203' port=1935 file='/tv2m/_definst_/smil:bnt2_mobile.smil/media_w616167019_b800000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=_6330.ts'
main debug: net: connecting to 185.4.83.203 port 1935
main debug: connection succeeded (socket = 2420)
access_http debug: protocol 'HTTP' answer code 200
access_http debug: Server: WowzaStreamingEngine/4.1.1
access_http debug: Content-Type: video/MP2T
access_http debug: this frame size=1222752
main debug: using access module "access_http"
main debug: Using stream method for AStream*
main debug: starting pre-buffering
main debug: received first data after 4 ms
main debug: pre-buffering done 1024 bytes in 0s - 249 KiB/s
main debug: removing module "access_http"
httplive debug: downloaded segment 6330 from stream 1
httplive debug: candidate 0 bandwidth (bits/s) 43283256 >= 300000
httplive debug: candidate 1 bandwidth (bits/s) 43283256 >= 800000
httplive debug: playing segment 6328 from stream 1
httplive debug: playing segment 6329 from stream 1
main debug: picture might be displayed late (missing 7 ms)
main debug: picture might be displayed late (missing 14 ms)
main warning: playback too late (73909): up-sampling
main warning: picture is too late to be displayed (missing 40 ms)
main debug: picture might be displayed late (missing 4 ms)
httplive warning: playback in danger of stalling
httplive debug: playing segment 6330 from stream 1
main debug: resampling stopped (drift: -17846 us)
main debug: picture might be displayed late (missing 6 ms)
httplive debug: Reloading HLS live meta playlist
main debug: creating access 'http' location='185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/chunklist_w616167019_b300000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=.m3u8', path='\\185.4.83.203:1935\tv2m\_definst_\smil:bnt2_mobile.smil\chunklist_w616167019_b300000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=.m3u8'
main debug: looking for access module matching "http": 20 candidates
access_http debug: querying proxy for http://185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/chunklist_w616167019_b300000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=.m3u8
access_http debug: no proxy
access_http debug: http: server='185.4.83.203' port=1935 file='/tv2m/_definst_/smil:bnt2_mobile.smil/chunklist_w616167019_b300000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=.m3u8'
main debug: net: connecting to 185.4.83.203 port 1935
main debug: connection succeeded (socket = 3084)
access_http debug: protocol 'HTTP' answer code 403
access_http error: error: HTTP/1.1 403 Forbidden
access_http debug: switching to HTTP version 1.0
main debug: net: connecting to 185.4.83.203 port 1935
main debug: connection succeeded (socket = 3084)
access_http debug: protocol 'HTTP' answer code 403
access_http error: error: HTTP/1.0 403 Forbidden
main debug: net: connecting to 185.4.83.203 port 1935
main debug: connection succeeded (socket = 3084)
access_mms error: error: HTTP/1.0 403 Forbidden
main debug: no access modules matched
main error: no suitable access module for `http://185.4.83.203:1935/tv2m/_definst_/smil:bnt2_mobile.smil/chunklist_w616167019_b300000_tkYnVsc2F0Q3VzdG9tUGFyYW1ldGVyPTEmYnVsc2F0ZW5kdGltZT0xNDE5NzYyMzI5JmJ1bHNhdHN0YXJ0dGltZT0xNDE5NzU0MDI5JmJ1bHNhdGhhc2g9cURNc1R6ZWFZbURRSHRId29lS1R3UURWUkdHaFZMZDFGTDBCc1JrN0Vycz0=.m3u8'