mirror of
https://github.com/wbt5/real-url.git
synced 2025-07-30 05:20:31 +08:00
Compare commits
3 Commits
6aaabad43a
...
5140702dba
Author | SHA1 | Date | |
---|---|---|---|
|
5140702dba | ||
|
b9c757ca62 | ||
|
6a008bf0e9 |
@ -12,7 +12,7 @@
|
||||
|
||||
目前已实现:
|
||||
|
||||
**50** 个直播平台的直播源获取:斗鱼直播、虎牙直播、哔哩哔哩直播、战旗直播、网易 CC 直播、火猫直播、企鹅电竞、YY 直播、一直播、快手直播、花椒直播、映客直播、西瓜直播、触手直播、NOW 直播、抖音直播,爱奇艺直播、酷狗直播、龙珠直播、PPS 奇秀直播、六间房、17 直播、来疯直播、优酷轮播台、网易 LOOK 直播、千帆直播、陌陌直播、小米直播、迅雷直播、京东直播、企鹅体育、人人直播、棉花糖直播、九秀直播、羚萌直播、95秀、新浪疯播、红人直播、艾米直播、KK直播、酷我聚星、乐嗨直播、秀色直播、星光直播、我秀直播、热猫直播、艺气山直播、AcFun 直播、猫耳FM、畅秀阁。
|
||||
**52** 个直播平台的直播源获取:斗鱼直播、虎牙直播、哔哩哔哩直播、战旗直播、网易 CC 直播、火猫直播、企鹅电竞、YY 直播、一直播、快手直播、花椒直播、映客直播、西瓜直播、触手直播、NOW 直播、抖音直播,爱奇艺直播、酷狗直播、龙珠直播、PPS 奇秀直播、六间房、17 直播、来疯直播、优酷轮播台、网易 LOOK 直播、千帆直播、陌陌直播、小米直播、迅雷直播、京东直播、企鹅体育、人人直播、棉花糖直播、九秀直播、羚萌直播、95秀、新浪疯播、红人直播、艾米直播、KK直播、酷我聚星、乐嗨直播、秀色直播、星光直播、我秀直播、热猫直播、艺气山直播、AcFun 直播、猫耳FM、畅秀阁、Twitch、TikTok。
|
||||
|
||||
**18** 个直播平台的弹幕获取:斗鱼直播、虎牙直播、哔哩哔哩直播、快手直播、火猫直播、企鹅电竞、花椒直播、映客直播、网易 CC 直播、酷狗直播、龙珠直播、PPS 奇秀、搜狐千帆、战旗直播、来疯直播、网易 LOOK 直播、AcFun 直播、艺气山直播。
|
||||
|
||||
@ -28,8 +28,9 @@
|
||||
有直播平台失效或新增其他平台解析的,可发 [issue](https://github.com/wbt5/real-url/issues/new)。
|
||||
|
||||
## 更新
|
||||
2021.05.02:新增 Twitch、TikTok。
|
||||
|
||||
2020.12.20:新增畅秀阁、猫耳FM。
|
||||
2021.05.01:新增畅秀阁、猫耳FM。
|
||||
|
||||
2020.12.20:修复直播源:抖音、艺气山、花椒、快手、来疯、龙珠、PPS、人人直播、17live 可能需要挂代理。
|
||||
|
||||
|
43
tiktok.py
Normal file
43
tiktok.py
Normal file
@ -0,0 +1,43 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time: 2021/5/2 23:23
|
||||
# @Project: real-url
|
||||
# @Author: wbt5
|
||||
# @Blog: https://wbt5.com
|
||||
|
||||
import re
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class TikTok:
|
||||
|
||||
def __init__(self, rid):
|
||||
self.rid = rid
|
||||
|
||||
def get_real_url(self):
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, '
|
||||
'like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
|
||||
}
|
||||
res = requests.get(self.rid, headers=headers).text
|
||||
url = re.search(r'"LiveUrl":"(.*?m3u8)",', res)
|
||||
|
||||
if url:
|
||||
return url.group(1)
|
||||
else:
|
||||
raise Exception('link invalid')
|
||||
|
||||
|
||||
def get_real_url(rid):
|
||||
try:
|
||||
tt = TikTok(rid)
|
||||
return tt.get_real_url()
|
||||
except Exception as e:
|
||||
print('Exception:', e)
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# https://vm.tiktok.com/ZMe45tomE
|
||||
r = input('请输入 TikTok 分享链接:\n')
|
||||
print(get_real_url(r))
|
93
twitch.py
Normal file
93
twitch.py
Normal file
@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time: 2021/5/2 16:20
|
||||
# @Project: real-url
|
||||
# @Author: wbt5
|
||||
# @Blog: https://wbt5.com
|
||||
|
||||
import json
|
||||
import re
|
||||
from urllib.parse import urlencode
|
||||
|
||||
# twitch 直播需要科学上网
|
||||
import requests
|
||||
|
||||
|
||||
class Twitch:
|
||||
|
||||
def __init__(self, rid):
|
||||
# rid = channel_name
|
||||
self.rid = rid
|
||||
with requests.Session() as self.s:
|
||||
pass
|
||||
|
||||
def get_client_id(self):
|
||||
try:
|
||||
res = self.s.get(f'https://www.twitch.tv/{self.rid}').text
|
||||
client_id = re.search(r'"Client-ID":"(.*?)"', res).group(1)
|
||||
return client_id
|
||||
except requests.exceptions.ConnectionError:
|
||||
raise Exception('ConnectionError')
|
||||
|
||||
def get_sig_token(self):
|
||||
data = {
|
||||
"operationName": "PlaybackAccessToken_Template",
|
||||
"query": "query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, "
|
||||
"$isVod: Boolean!, $playerType: String!) { streamPlaybackAccessToken(channelName: $login, "
|
||||
"params: {platform: \"web\", playerBackend: \"mediaplayer\", playerType: $playerType}) @include("
|
||||
"if: $isLive) { value signature __typename } videoPlaybackAccessToken(id: $vodID, "
|
||||
"params: {platform: \"web\", playerBackend: \"mediaplayer\", playerType: $playerType}) @include("
|
||||
"if: $isVod) { value signature __typename }}",
|
||||
"variables": {
|
||||
"isLive": True,
|
||||
"login": self.rid,
|
||||
"isVod": False,
|
||||
"vodID": "",
|
||||
"playerType": "site"
|
||||
}
|
||||
}
|
||||
|
||||
headers = {
|
||||
'Client-ID': self.get_client_id(),
|
||||
'Referer': 'https://www.twitch.tv/',
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
|
||||
'Chrome/90.0.4430.93 Safari/537.36',
|
||||
}
|
||||
res = self.s.post('https://gql.twitch.tv/gql', headers=headers, data=json.dumps(data)).json()
|
||||
try:
|
||||
token, signature, _ = res['data']['streamPlaybackAccessToken'].values()
|
||||
except AttributeError:
|
||||
raise Exception("Channel does not exist")
|
||||
|
||||
return signature, token
|
||||
|
||||
def get_real_url(self):
|
||||
signature, token = self.get_sig_token()
|
||||
params = {
|
||||
'allow_source': 'true',
|
||||
'dt': 2,
|
||||
'fast_bread': 'true',
|
||||
'player_backend': 'mediaplayer',
|
||||
'playlist_include_framerate': 'true',
|
||||
'reassignments_supported': 'true',
|
||||
'sig': signature,
|
||||
'supported_codecs': 'vp09,avc1',
|
||||
'token': token,
|
||||
'cdm': 'wv',
|
||||
'player_version': '1.4.0',
|
||||
}
|
||||
url = f'https://usher.ttvnw.net/api/channel/hls/{self.rid}.m3u8?{urlencode(params)}'
|
||||
return url
|
||||
|
||||
|
||||
def get_real_url(rid):
|
||||
try:
|
||||
tw = Twitch(rid)
|
||||
return tw.get_real_url()
|
||||
except Exception as e:
|
||||
print('Exception:', e)
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
r = input('请输入 twitch 房间名:\n')
|
||||
print(get_real_url(r))
|
Loading…
x
Reference in New Issue
Block a user