mirror of
https://github.com/streamlink/streamlink
synced 2024-11-16 05:03:49 +01:00
Add plugin for huajiao.com and zhanqi.tv (#334)
* huajiao.com and zhanqi.tv docs added * Add source huajiao.com * Add source zhanqi.tv * fixed minor problems according to @steven7851 * STREAM_WEIGHTS added, hls source not recommanded * Fix compatibility with --stream-types and --stream-priority * Change to Schema parser * Fixes the problem with HLS. When m3u8 field is provided in json, request to http stream will result in a 404 Not found. That means either HLS or HTTP is available. ` Input #0, mpegts, from 'pipe:0': Duration: N/A, start: 40169.165733, bitrate: 60 kb/s Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0.0[0x100]: Video: h264 (High), yuv420p, 504x896, 15 fps, 90k tbn Stream #0.1[0x101]: Audio: aac, 44100 Hz, mono, fltp, 60 kb/s ` ` Input #0, flv, from 'pipe:0': Metadata: copyright : lvll hasVideo : true hasAudio : true displayWidth : 504 displayHeight : 896 Duration: N/A, start: 0.000000, bitrate: N/A Stream #0.0: Video: h264 (High), yuv420p, 504x896, 14.42 fps, 1k tbn Stream #0.1: Audio: aac, 44100 Hz, mono, fltp ` HLS and HTTP stream seems to have different quality, HLS is better than HTTP. But either is available, so `STREAM_WEIGHTS` not set and only an `live` option provided. * Stream name set to 'live' * remove classmethod `stream_weight` because `live` already have pre-defined method
This commit is contained in:
parent
0139944f70
commit
ac4abdd542
@ -70,6 +70,7 @@ gaminglive gaminglive.tv Yes Yes
|
||||
gomexp gomexp.com Yes No
|
||||
goodgame goodgame.ru Yes No Only HLS streams are available.
|
||||
hitbox hitbox.tv Yes Yes
|
||||
huajiao huajiao.com Yes No
|
||||
ine ine.com --- Yes
|
||||
itvplayer itv.com/itvplayer Yes Yes Streams may be geo-restricted to Great Britain.
|
||||
kanal7 kanal7.com Yes No
|
||||
@ -165,6 +166,7 @@ younow younow.com Yes --
|
||||
youtube - youtube.com Yes Yes Protected videos are not supported.
|
||||
- youtu.be
|
||||
zdf_mediathek zdf.de Yes Yes
|
||||
zhanqitv zhanqi.tv Yes No
|
||||
=================== ==================== ===== ===== ===========================
|
||||
|
||||
|
||||
|
62
src/streamlink/plugins/huajiao.py
Normal file
62
src/streamlink/plugins/huajiao.py
Normal file
@ -0,0 +1,62 @@
|
||||
import base64
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
import random
|
||||
import json
|
||||
|
||||
from requests.adapters import HTTPAdapter
|
||||
|
||||
from streamlink.plugin import Plugin
|
||||
from streamlink.plugin.api import http, validate
|
||||
from streamlink.stream import (HTTPStream, HLSStream)
|
||||
|
||||
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"
|
||||
HUAJIAO_URL = "http://www.huajiao.com/l/{}"
|
||||
LAPI_URL = "http://g2.live.360.cn/liveplay?stype=flv&channel={}&bid=huajiao&sn={}&sid={}&_rate=xd&ts={}&r={}&_ostype=flash&_delay=0&_sign=null&_ver=13"
|
||||
|
||||
_url_re = re.compile("""
|
||||
http(s)?://(www\.)?huajiao.com
|
||||
/l/(?P<channel>[^/]+)
|
||||
""", re.VERBOSE)
|
||||
|
||||
_feed_json_re = re.compile(r'^\s*var\s*feed\s*=\s*(?P<feed>{.*})\s*;', re.MULTILINE)
|
||||
|
||||
_feed_json_schema = validate.Schema(
|
||||
validate.all(
|
||||
validate.transform(_feed_json_re.search),
|
||||
validate.any(
|
||||
None,
|
||||
validate.all(
|
||||
validate.get('feed'),
|
||||
validate.transform(json.loads)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
class Huajiao(Plugin):
|
||||
@classmethod
|
||||
def can_handle_url(self, url):
|
||||
return _url_re.match(url)
|
||||
|
||||
def _get_streams(self):
|
||||
match = _url_re.match(self.url)
|
||||
channel = match.group("channel")
|
||||
|
||||
http.headers.update({"User-Agent": USER_AGENT})
|
||||
http.verify=False
|
||||
|
||||
feed_json = http.get(HUAJIAO_URL.format(channel), schema=_feed_json_schema)
|
||||
if feed_json['feed']['m3u8']:
|
||||
stream = HLSStream(self.session, feed_json['feed']['m3u8'])
|
||||
else:
|
||||
sn = feed_json['feed']['sn']
|
||||
channel_sid = feed_json['relay']['channel']
|
||||
sid = uuid.uuid4().hex.upper()
|
||||
encoded_json = http.get(LAPI_URL.format(channel_sid, sn, sid, time.time(), random.random())).content
|
||||
decoded_json = base64.decodestring(encoded_json[0:3] + encoded_json[6:]).decode('utf-8')
|
||||
video_data = json.loads(decoded_json)
|
||||
stream = HTTPStream(self.session, video_data['main'])
|
||||
yield "live", stream
|
||||
|
||||
__plugin__ = Huajiao
|
97
src/streamlink/plugins/zhanqi.py
Normal file
97
src/streamlink/plugins/zhanqi.py
Normal file
@ -0,0 +1,97 @@
|
||||
import re
|
||||
|
||||
from streamlink.plugin import Plugin
|
||||
from streamlink.plugin.api import http, validate
|
||||
from streamlink.plugin.api.utils import parse_json
|
||||
from streamlink.stream import (
|
||||
HTTPStream, HLSStream
|
||||
)
|
||||
|
||||
API_URL = "http://www.zhanqi.tv/api/static/live.roomid/{roomID[id]}.json"
|
||||
|
||||
STATUS_ONLINE = 4
|
||||
STATUS_OFFLINE = 0
|
||||
|
||||
#hls source is not stable, lower priority
|
||||
STREAM_WEIGHTS = {
|
||||
"live": 1080
|
||||
}
|
||||
|
||||
_url_re = re.compile("""
|
||||
http(s)?://(www\.)?zhanqi.tv
|
||||
/(?P<channel>[^/]+)
|
||||
""", re.VERBOSE)
|
||||
|
||||
_json_re = re.compile(r"window\.oPageConfig\.oRoom\s*=\s*({.+?});")
|
||||
|
||||
_roomID_schema = validate.Schema(
|
||||
validate.all(
|
||||
validate.transform(_json_re.search),
|
||||
validate.any(
|
||||
None,
|
||||
validate.all(
|
||||
validate.get(1),
|
||||
validate.transform(parse_json),
|
||||
{
|
||||
"id": validate.all(
|
||||
validate.text,
|
||||
validate.transform(int)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
_room_schema = validate.Schema(
|
||||
{
|
||||
"data": validate.any(None, {
|
||||
"status": validate.all(
|
||||
validate.text,
|
||||
validate.transform(int)
|
||||
),
|
||||
"videoId": validate.text
|
||||
})
|
||||
},
|
||||
validate.get("data")
|
||||
)
|
||||
|
||||
|
||||
class Zhanqitv(Plugin):
|
||||
@classmethod
|
||||
def can_handle_url(self, url):
|
||||
return _url_re.match(url)
|
||||
|
||||
@classmethod
|
||||
def stream_weight(cls, stream):
|
||||
if stream in STREAM_WEIGHTS:
|
||||
return STREAM_WEIGHTS[stream], "zhanqitv"
|
||||
return Plugin.stream_weight(stream)
|
||||
|
||||
def _get_streams(self):
|
||||
match = _url_re.match(self.url)
|
||||
channel = match.group("channel")
|
||||
|
||||
roomID = http.get(self.url, schema=_roomID_schema)
|
||||
|
||||
res = http.get(API_URL.format(roomID=roomID))
|
||||
room = http.json(res, schema=_room_schema)
|
||||
if not room:
|
||||
self.logger.info("Not a valid room url.")
|
||||
return
|
||||
|
||||
if room["status"] != STATUS_ONLINE:
|
||||
self.logger.info("Stream current unavailable.")
|
||||
return
|
||||
|
||||
hls_url = "http://dlhls.cdn.zhanqi.tv/zqlive/{room[videoId]}_1024/index.m3u8?Dnion_vsnae={room[videoId]}".format(room=room)
|
||||
hls_stream = HLSStream(self.session, hls_url)
|
||||
if hls_stream:
|
||||
yield "hls", hls_stream
|
||||
|
||||
http_url = "http://wshdl.load.cdn.zhanqi.tv/zqlive/{room[videoId]}.flv?get_url=".format(room=room)
|
||||
http_stream = HTTPStream(self.session, http_url)
|
||||
if http_stream:
|
||||
yield "http", http_stream
|
||||
|
||||
__plugin__ = Zhanqitv
|
Loading…
Reference in New Issue
Block a user