mirror of
https://github.com/hjdhnx/dr_py.git
synced 2025-05-01 03:54:01 -04:00
增加后端代理,解决部分网页的播放问题
This commit is contained in:
parent
407d8aa791
commit
cb03151232
25
app.py
25
app.py
@ -9,11 +9,12 @@ from flask_migrate import Migrate
|
||||
from base import config
|
||||
from base.database import db
|
||||
from utils.log import logger
|
||||
from utils.system import get_wlan_info,getHost
|
||||
from utils.system import get_wlan_info, getHost
|
||||
from controllers import *
|
||||
from js.rules import getRuleLists
|
||||
import sys
|
||||
|
||||
|
||||
def create_flask_app():
|
||||
app = Flask(__name__, static_folder='static', static_url_path='/static')
|
||||
app.config.from_object(config) # 单独的配置文件里写了,这里就不用弄json中文显示了
|
||||
@ -31,22 +32,28 @@ def create_flask_app():
|
||||
# logger.info(f"自定义播放解析地址:{lsg.getItem('PLAY_URL')}")
|
||||
logger.info(f'当前操作系统{sys.platform}')
|
||||
rule_list = getRuleLists()
|
||||
wlan_info,_ = get_wlan_info()
|
||||
wlan_info, _ = get_wlan_info()
|
||||
logger.info(rule_list)
|
||||
logger.info(f'局域网: {getHost(1, app.config.get("HTTP_PORT"))}/index\n本地: {getHost(0, app.config.get("HTTP_PORT"))}/index\nwlan_info:{wlan_info}')
|
||||
logger.info(
|
||||
f'局域网: {getHost(1, app.config.get("HTTP_PORT"))}/index\n本地: {getHost(0, app.config.get("HTTP_PORT"))}/index\nwlan_info:{wlan_info}')
|
||||
db.init_app(app)
|
||||
db.app = app
|
||||
db.create_all(app=app)
|
||||
return app
|
||||
|
||||
|
||||
app = create_flask_app()
|
||||
migrate = Migrate(app, db)
|
||||
|
||||
now_python_ver = ".".join([str(i) for i in sys.version_info[:3]])
|
||||
if sys.version_info < (3,9):
|
||||
if sys.version_info < (3, 9):
|
||||
from gevent.pywsgi import WSGIServer
|
||||
|
||||
# from gevent import monkey
|
||||
# monkey.patch_socket() # 开启socket异步
|
||||
# monkey.patch_all() # 多线程,只能放在最开头,import其它包之前
|
||||
|
||||
from gevent import monkey
|
||||
monkey.patch_socket() # 开启socket异步
|
||||
print(f'当前python版本{now_python_ver}为3.9.0及以下,支持gevent')
|
||||
else:
|
||||
print(f'当前python版本{now_python_ver}为3.9.0及以上,不支持gevent')
|
||||
@ -54,10 +61,16 @@ else:
|
||||
if __name__ == "__main__":
|
||||
http_port = int(app.config.get('HTTP_PORT', 5705))
|
||||
http_host = app.config.get('HTTP_HOST', '0.0.0.0')
|
||||
threaded = app.config.get('Thread')
|
||||
if threaded is None:
|
||||
threaded = True
|
||||
# https://www.zhihu.com/question/64096559
|
||||
print('threaded:',threaded)
|
||||
# if sys.version_info < (3, 9) and not sys.platform.startswith('win'):
|
||||
if sys.version_info < (3, 9):
|
||||
# server = WSGIServer(('0.0.0.0', 5705), app, handler_class=WebSocketHandler,log=app.logger)
|
||||
# server = WSGIServer(('0.0.0.0', 5705), app, handler_class=WebSocketHandler,log=None)
|
||||
server = WSGIServer((http_host, http_port), app, log=logger)
|
||||
server.serve_forever()
|
||||
else:
|
||||
app.run(debug=False, host=http_host, port=http_port)
|
||||
app.run(debug=False, host=http_host, port=http_port, threaded=threaded)
|
@ -56,3 +56,4 @@ JS_PROXY = 'http://localhost:5705/admin/view/=>https://ghproxy.net/https://raw.g
|
||||
ALI_TOKEN = '' # 适用于初始配置的阿里云token
|
||||
ENV = '{"bili_cookie":""}' # 自定义环境变量
|
||||
UPDATE_PROXY = 'https://ghproxy.net/' # 检测升级代理
|
||||
Thread = True # 开启windows多线程调用
|
||||
|
@ -6,10 +6,11 @@
|
||||
import functools
|
||||
import json
|
||||
import os
|
||||
|
||||
from urllib.parse import urljoin
|
||||
import requests
|
||||
from flask import Blueprint, abort, request, render_template, send_from_directory, render_template_string, jsonify, \
|
||||
make_response, redirect, \
|
||||
current_app
|
||||
current_app, url_for
|
||||
from time import time
|
||||
from utils.web import getParmas, get_interval
|
||||
from utils.cfg import cfg
|
||||
@ -38,12 +39,14 @@ def custom_static_cms(filename):
|
||||
# print(filename)
|
||||
return send_from_directory('templates/cms', filename)
|
||||
|
||||
|
||||
@web.route('/player/<path:filename>')
|
||||
def custom_static_player(filename):
|
||||
# 自定义静态目录 {{ url_for('custom_static',filename='help.txt')}}
|
||||
# print(filename)
|
||||
return send_from_directory('templates/player', filename)
|
||||
|
||||
|
||||
@web.route('/<web_name>/<theme>')
|
||||
def web_index(web_name, theme):
|
||||
ctx = {'web_name': web_name, 'key': '关键词', 'description': '描述'}
|
||||
@ -67,7 +70,7 @@ def web_index(web_name, theme):
|
||||
ctx['tid'] = tid
|
||||
ctx['tname'] = tname
|
||||
ctx['url'] = url
|
||||
print('tid:',tid)
|
||||
print('tid:', tid)
|
||||
|
||||
file_path = os.path.abspath(f'js/{web_name}.js')
|
||||
print(file_path)
|
||||
@ -86,4 +89,51 @@ def web_index(web_name, theme):
|
||||
else:
|
||||
return render_template(f'cms/{theme}/homeContent.html', ctx=ctx)
|
||||
except Exception as e:
|
||||
return render_template('404.html', ctx=ctx, error=f'发生错误的原因可能是下面路径未找到:{e}')
|
||||
return render_template('404.html', ctx=ctx, error=f'发生错误的原因可能是下面路径未找到:{e}')
|
||||
|
||||
|
||||
@web.route('/302redirect')
|
||||
def get302UrlResponse():
|
||||
url = getParmas('url')
|
||||
if not url:
|
||||
abort(403)
|
||||
params = {}
|
||||
if not url.startswith('http'):
|
||||
url = urljoin(request.root_url, url)
|
||||
# url = urljoin('http://localhost:5705/',url)
|
||||
print(url)
|
||||
items = url.split('vod?')[1].split('&')
|
||||
for item in items:
|
||||
params[item.split('=')[0]] = item.split('=')[1]
|
||||
print(params)
|
||||
# abort(403)
|
||||
|
||||
timeout = getParmas('timeout') or 5000
|
||||
rurl = url
|
||||
try:
|
||||
timeout = int(timeout)
|
||||
headers = {
|
||||
# 'referer': url,
|
||||
'user-agent': 'Mozilla/5.0'
|
||||
}
|
||||
print('开始调用接口:', url)
|
||||
r = requests.get(url, headers=headers, timeout=timeout, verify=False)
|
||||
rurl = r.url
|
||||
|
||||
# rurl = url_for('vod.vod_home', **params)
|
||||
# print(rurl)
|
||||
print('结束调用接口:', rurl)
|
||||
return jsonify({
|
||||
'url': rurl,
|
||||
'redirect': rurl != url,
|
||||
'data': r.text,
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.info(f'发生了错误:{e}')
|
||||
return jsonify({
|
||||
'url': rurl,
|
||||
'redirect': rurl != url,
|
||||
'data': None,
|
||||
'error': f'{e}',
|
||||
})
|
||||
|
@ -1 +1 @@
|
||||
3.9.41beta26
|
||||
3.9.41beta27
|
@ -277,7 +277,7 @@
|
||||
{% for rule in rules.list %}
|
||||
<div class="red">
|
||||
<div class="mz"><a class="view" href="javascript:void(0);">{{ rule.name }}</a></div>
|
||||
<div class="sa"><a class="preview_home" href="/web/{{ rule.name }}/mxpro" value="{{ rule.name }}">🌐</a></div>
|
||||
<div class="sa"><a class="preview_home" href="/web/{{ rule.name }}/mxpro" value="{{ rule.name }}" target="_blank">🌐</a></div>
|
||||
<div class="sj"><a class="view_home" href="javascript:void(0);" value="{{ rule.name }}">🏠</a></div>
|
||||
<div class="ss"><a class="view_search" href="javascript:void(0);" value="{{ rule.name }}">🔍️</a></div>
|
||||
<div class="sc"><a class="clear" href="javascript:void(0);" value="{{ rule.name }}">🗑</a></div>
|
||||
|
@ -22,6 +22,7 @@
|
||||
<script src="/static/js/axios.min.js"></script>
|
||||
<script src="/static/js/eruda.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/web/cms/mxpro/js/commonUtil.js"></script>
|
||||
<script src="/web/cms/mxpro/js/commonUI.js"></script>
|
||||
<link rel="stylesheet" href="/web/cms/mxpro/css/commonUI.css" type="text/css" />
|
||||
<script>var maccms={"path":"","mid":"1","url":"5imv.cc","wapurl":"www.5imv.cc","mob_status":"2"};</script>
|
||||
@ -243,39 +244,72 @@ const app = createApp({
|
||||
const photoVisible = ref(false);
|
||||
const iframeRef = ref(null);
|
||||
var sniffer;
|
||||
|
||||
const {isVideo,getRealUrl} = commonUtil;
|
||||
// get302UrlResponse('/vod?pwd=dzyyds&rule=007影视&ext=&play_url=https%3A//www.007ts.me/play/69636-3-1.html',(resp)=>{
|
||||
// console.log('重定向到:',resp);
|
||||
// });
|
||||
// getRealUrl('/vod?pwd=dzyyds&rule=007影视&ext=&play_url=https%3A//www.007ts.me/play/69636-3-1.html',(res)=>{
|
||||
// console.log('重定向到:',res);
|
||||
// });
|
||||
const methods = {
|
||||
async lazyPlay(url){
|
||||
iframeShow.value = true;
|
||||
console.log('准备处理播放地址:'+url);
|
||||
clearInterval(sniffer);
|
||||
try {
|
||||
if(/\.(m3u8|mp4)/.test(url)){
|
||||
if(isVideo(url)){
|
||||
console.log('直接播放');
|
||||
methods.setPlayUrl(url);
|
||||
return
|
||||
}
|
||||
const res = await axios.get(url,{maxRedirects: 0});
|
||||
const { status, headers: { Location } } = res;
|
||||
// console.log(status);
|
||||
console.log(res.request.responseURL);
|
||||
if (status === 302) {
|
||||
console.log(Location);
|
||||
const res =await getRealUrl(url,(resp)=>{
|
||||
// console.log('代理数据:',resp.data);
|
||||
return resp.data
|
||||
});
|
||||
// console.log(res);
|
||||
let res_data = res.data;
|
||||
try {
|
||||
res_data = JSON.parse(res_data);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
console.log(res.data);
|
||||
if(typeof(res.data)==='string' && /#EXTM3U/.test(res.data)){
|
||||
// console.log(res_data);
|
||||
// console.log(res.url);
|
||||
// console.log(res.redirect);
|
||||
if(res.redirect){ // 重定向的直接设置播放器的值
|
||||
if(isVideo(res.url)){ // 判断重定向的为直链
|
||||
methods.setPlayUrl(res.url);
|
||||
}else{
|
||||
console.log('重定向待嗅探页面,但是由于跨域问题,只好内嵌播放页播放');
|
||||
iframeSrc.value = res.url;
|
||||
}
|
||||
return
|
||||
// throw new Error('重定向网页直接播放,尝试嗅探(存在跨域无法嗅探问题,暂时考虑直接内嵌人家的播放页)');
|
||||
}
|
||||
|
||||
// const res = await axios.get(url,{maxRedirects: 0});
|
||||
// const { status, headers: { Location } } = res;
|
||||
// // console.log(status);
|
||||
// console.log(res.request.responseURL);
|
||||
// if (status === 302) {
|
||||
// console.log(Location);
|
||||
// }
|
||||
// console.log(res.data);
|
||||
|
||||
console.log(res_data);
|
||||
if(typeof(res_data)==='string'){
|
||||
iframeRef.value.contentWindow.location.reload();
|
||||
iframeSrc.value = url;
|
||||
throw new Error('重定向类文件无法直接播放,尝试嗅探');
|
||||
} else if(!res.data.parse&&res.data.url){
|
||||
methods.setPlayUrl(res.data.url);
|
||||
}else if(/url=/.test(res.data.url)){
|
||||
iframeSrc.value = res.data.url;
|
||||
} else if((res.data.parse||res.data.jx)&&res.data.url){
|
||||
throw new Error('返回的数据是文本无法直接播放,尝试嗅探');
|
||||
} else if(!res_data.parse&&res_data.url){
|
||||
methods.setPlayUrl(res_data.url);
|
||||
}else if(/url=/.test(res_data.url)){
|
||||
iframeSrc.value = res_data.url;
|
||||
} else if((res_data.parse||res_data.jx)&&res_data.url){
|
||||
console.log(ctx.value);
|
||||
iframeSrc.value = res.data.url;
|
||||
iframeSrc.value = res_data.url;
|
||||
if(confirm('该视频来自其它正版地址,drpy网页暂未实现解析功能,是否跳到正版站通过油猴插件等手段播放?')){
|
||||
open(res.data.url);
|
||||
open(res_data.url);
|
||||
}
|
||||
}
|
||||
}catch (e) {
|
||||
@ -365,6 +399,7 @@ const app = createApp({
|
||||
photoVisible:photoVisible,
|
||||
iframeRef:iframeRef,
|
||||
sniffer:sniffer,
|
||||
isVideo,getRealUrl
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -392,6 +427,7 @@ eruda.init();
|
||||
<!--<script charset="UTF-8" id="LA_COLLECT" src="/web/cms/mxpro/js/js-sdk-pro.min.js"></script>-->
|
||||
<!--<script>LA.init({id:"JYQUFCtAOBTUMsNQ",ck:"JYQUFCtAOBTUMsNQ"})</script>-->
|
||||
<script type="text/javascript" src="/web/cms/mxpro/js/stui_default.js "></script>
|
||||
|
||||
<!--弹窗样式和自动弹窗方法-->
|
||||
<link rel="stylesheet" href="/web/cms/mxpro/css/notice.css" type="text/css">
|
||||
<script type="text/javascript" src="/web/cms/mxpro/js/mxhtml.js"></script>
|
||||
|
39
templates/cms/mxpro/js/commonUtil.js
Normal file
39
templates/cms/mxpro/js/commonUtil.js
Normal file
@ -0,0 +1,39 @@
|
||||
var commonUtil = {
|
||||
isVideo(playUrl){
|
||||
let res_url = playUrl.split('?')[0];
|
||||
if(playUrl.endsWith('.m3u8')||res_url.endsWith('.m3u8')){
|
||||
return true
|
||||
}else if(playUrl.endsWith('.mp4')||res_url.endsWith('.mp4')){
|
||||
return true
|
||||
}else if(/\.(m4a|mp3|flv|aac)$/.test(playUrl)||/\.(m4a|mp3|flv|aac)$/.test(res_url)){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
getLocationFromRedirect(
|
||||
originUrl,
|
||||
method = "GET"
|
||||
){
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(method, originUrl, true);
|
||||
xhr.onload = function () {
|
||||
resolve(xhr.responseURL);
|
||||
};
|
||||
xhr.onerror = reject;
|
||||
xhr.send(null);
|
||||
})
|
||||
},
|
||||
get302UrlResponse(url, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url, true);
|
||||
xhr.onload = function () {
|
||||
callback(xhr.responseURL);
|
||||
}
|
||||
xhr.send(null);
|
||||
},
|
||||
async getRealUrl(url,callback){
|
||||
const res = await axios.get(`web/302redirect?url=${encodeURIComponent(url)}`);
|
||||
return callback(res);
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user