页面及逻辑修改

This commit is contained in:
Jerry Yan 2019-04-08 11:32:05 +08:00
parent 99d148666e
commit c3a965f284
7 changed files with 225 additions and 19 deletions

View File

@ -15,6 +15,7 @@ def reloadConfig():
config = json.load(_config_fp)
_config_fp.close()
dt_format="%Y/%m/%d %H:%M:%S"
broadcaster = ""
@ -23,6 +24,7 @@ isBroadcasting = False
updateTime = ""
forceStopDownload = False
forceNotBroadcasting = False
uploadQueue = queue.Queue()
encodeQueue = queue.Queue()
@ -33,6 +35,18 @@ encodeStatus = []
errors = []
def parseSize(size):
K = size/1024.0
if K > 1000:
M = K/1024.0
if M > 1000:
return "{:.2f}GB".format(M / 1024.0)
else:
return "{:.2f}MB".format(M)
else:
return "{:.2f}MB".format(K)
def appendUploadStatus(obj):
global uploadStatus
if isinstance(obj, dict):
@ -44,7 +58,7 @@ def appendUploadStatus(obj):
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
uploadStatus = uploadStatus[-10:]
uploadStatus = uploadStatus[-config["l_c"]:]
def modifyLastUploadStatus(obj):
@ -69,7 +83,7 @@ def appendEncodeStatus(obj):
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
encodeStatus = encodeStatus[-10:]
encodeStatus = encodeStatus[-config["l_c"]:]
def modifyLastEncodeStatus(obj):
@ -94,7 +108,7 @@ def appendDownloadStatus(obj):
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
downloadStatus = downloadStatus[-10:]
downloadStatus = downloadStatus[-config["l_c"]:]
def modifyLastDownloadStatus(obj):
@ -119,7 +133,7 @@ def appendError(obj):
"datetime": datetime.strftime(datetime.now(), dt_format),
"message": str(obj)
})
errors = errors[-10:]
errors = errors[-config["elc"]:]
class downloader(XiGuaLiveApi):
@ -127,7 +141,7 @@ class downloader(XiGuaLiveApi):
playlist = None
def updRoomInfo(self):
global broadcaster, isBroadcasting, updateTime
global broadcaster, isBroadcasting, updateTime, forceNotBroadcasting, forceStopDownload
super(downloader, self).updRoomInfo()
updateTime = datetime.strftime(datetime.now(), dt_format)
broadcaster = self.roomLiver
@ -135,6 +149,9 @@ class downloader(XiGuaLiveApi):
if self.isLive:
self.updPlayList()
else:
forceStopDownload = False
forceNotBroadcasting = False
self.playlist = False
self.files = []
def updPlayList(self):

View File

@ -1,6 +1,8 @@
import os
from glob import glob
from time import sleep
from flask_cors import CORS
from flask import Flask, jsonify, request, redirect, url_for
from flask import Flask, jsonify, request, redirect, render_template, Response
import Common
import threading
from liveDownloader import run as RUN
@ -58,19 +60,25 @@ def getAllStats():
return jsonify({"message":"ok","code":200,"status":0,"data":{
"download":Common.downloadStatus,
"encode": Common.encodeStatus,
"encodeQueueSize": Common.encodeQueue.qsize(),
"upload": Common.uploadStatus,
"uploadQueueSize": Common.uploadQueue.qsize(),
"error": Common.errors,
"broadcast": {
"broadcaster": Common.broadcaster.__str__(),
"isBroadcasting": Common.isBroadcasting,
"streamUrl": Common.streamUrl,
"updateTime": Common.updateTime
},
"config": {
"forceNotBroadcasting": Common.forceNotBroadcasting,
"forceStopDownload": Common.forceStopDownload,
}
}})
@app.route("/stats/broadcast", methods=["GET"])
def geBroadcastStats():
def getBroadcastStats():
return jsonify({"message":"ok","code":200,"status":0,"data":{
"broadcast": {
"broadcaster": Common.broadcaster.__str__(),
@ -81,8 +89,18 @@ def geBroadcastStats():
}})
@app.route("/stats/config", methods=["GET"])
def getConfigStats():
return jsonify({"message":"ok","code":200,"status":0,"data":{
"config": {
"forceNotBroadcasting": Common.forceNotBroadcasting,
"forceStopDownload": Common.forceStopDownload,
}
}})
@app.route("/stats/download", methods=["GET"])
def geDownloadStats():
def getDownloadStats():
return jsonify({"message":"ok","code":200,"status":0,"data":{
"download":Common.downloadStatus,
}})
@ -92,6 +110,7 @@ def geDownloadStats():
def getEncodeStats():
return jsonify({"message":"ok","code":200,"status":0,"data":{
"encode": Common.encodeStatus,
"encodeQueueSize": Common.encodeQueue.qsize(),
}})
@ -99,9 +118,30 @@ def getEncodeStats():
def getUploadStats():
return jsonify({"message":"ok","code":200,"status":0,"data":{
"upload": Common.uploadStatus,
"uploadQueueSize": Common.uploadQueue.qsize(),
}})
@app.route("/files/", methods=["GET"])
def fileIndex():
a = []
for i in (glob("*.mp4") + glob("*.flv")):
a.append({
"name": i,
"size": Common.parseSize(os.path.getsize(i))
})
return render_template("files.html",files=a)
@app.route("/files/download/<path>", methods=["GET"])
def fileDownload(path):
def generate(file):
with open(file, "rb") as f:
for row in f:
yield row
return Response(generate(path), mimetype='application/octet-stream')
def SubThread():
t = threading.Thread(target=RUN, args=(Common.config['l_u'],))
t.setDaemon(True)

View File

@ -4,6 +4,7 @@ import os
import re
import json as JSON
from datetime import datetime
from time import sleep
from Common import appendUploadStatus, modifyLastUploadStatus
import rsa
import math
@ -11,7 +12,7 @@ import base64
import hashlib
import requests
from urllib import parse
requests.adapters.DEFAULT_RETRIES = 10
class VideoPart:
def __init__(self, path, title='', desc=''):
@ -25,6 +26,7 @@ class Bilibili:
self.files = []
self.videos = []
self.session = requests.session()
self.session.keep_alive = False
if cookie:
self.session.headers["cookie"] = cookie
self.csrf = re.search('bili_jct=(.*?);', cookie).group(1)
@ -203,6 +205,7 @@ class Bilibili:
filepath = part.path
filename = os.path.basename(filepath)
filesize = os.path.getsize(filepath)
appendUploadStatus("Upload >{}< Started".format(filepath))
self.files.append(part)
r = self.session.get('https://member.bilibili.com/preupload?'
'os=upos&upcdn=ws&name={name}&size={size}&r=upos&profile=ugcupos%2Fyb&ssl=0'
@ -237,12 +240,13 @@ class Bilibili:
# {"upload_id":"72eb747b9650b8c7995fdb0efbdc2bb6","key":"\/i181012ws2wg1tb7tjzswk2voxrwlk1u.mp4","OK":1,"bucket":"ugc"}
json = r.json()
upload_id = json['upload_id']
appendUploadStatus("Upload >{}< Started".format(filepath))
with open(filepath, 'rb') as f:
chunks_num = math.ceil(filesize / chunk_size)
chunks_index = 0
chunks_data = f.read(chunk_size)
modifyLastUploadStatus("Uploading >{}< @ {:.2f}%".format(filepath, 100.0 * chunks_index / chunks_num))
while True:
_d = datetime.now()
if not chunks_data:
break
r = self.session.put('https:{endpoint}/{upos_uri}?'
@ -265,6 +269,8 @@ class Bilibili:
chunks_data = f.read(chunk_size)
chunks_index += 1 # start with 0
modifyLastUploadStatus("Uploading >{}< @ {:.2f}%".format(filepath, 100.0*chunks_index/chunks_num))
if (datetime.now()-_d).seconds < 2:
sleep(1)
# NOT DELETE! Refer to https://github.com/comwrg/bilibiliupload/issues/15#issuecomment-424379769
self.session.post('https:{endpoint}/{upos_uri}?'
@ -330,7 +336,7 @@ class Bilibili:
"order_id": 0,
"videos": self.videos}
)
appendUploadStatus(">{}< Published | Result : {}".format(title, r.text))
appendUploadStatus("[{}] Published | Result : {}".format(title, r.text))
def reloadFromPrevious(self):
if os.path.exists("uploaded.json"):

View File

@ -17,20 +17,20 @@ def download(url):
path = datetime.strftime(datetime.now(), "%Y%m%d_%H%M.flv")
p = requests.get(url, stream=True)
if p.status_code != 200:
appendDownloadStatus("Download [{}] Response 404 ,will stop looping".format(url))
appendDownloadStatus("Download with Response 404, maybe broadcaster is not broadcasting")
return True
isDownload = True
appendDownloadStatus("Starting Download >{}<".format(path))
appendDownloadStatus("Download >{}< Start".format(path))
f = open(path, "wb")
try:
for t in p.iter_content(chunk_size=64 * 1024):
if t:
f.write(t)
_size = os.path.getsize(path)
modifyLastDownloadStatus("Download >{}< @ {:.2f}%".format(path, 100.0 * _size/config["p_s"]))
modifyLastDownloadStatus("Downloading >{}< @ {:.2f}%".format(path, 100.0 * _size/config["p_s"]))
if _size > config["p_s"] or forceStopDownload:
break
modifyLastDownloadStatus("Finished Download >{}<".format(path))
modifyLastDownloadStatus("Download >{}< Finished".format(path))
except Exception as e:
appendError("Download >{}< With Exception {}".format(path, datetime.strftime(datetime.now(), "%y%m%d %H%M"),
e.__str__()))
@ -53,10 +53,10 @@ def encode():
i = encodeQueue.get()
if os.path.exists(i):
isEncode = True
appendEncodeStatus("Start Encoding >{}<".format(i))
appendEncodeStatus("Encoding >{}< Start".format(i))
os.system("ffmpeg -i {} -c:v copy -c:a copy -f mp4 {} -y".format(i, i[:13] + ".mp4"))
uploadQueue.put(i[:13] + ".mp4")
modifyLastEncodeStatus("Finished Encoding >{}<".format(i))
modifyLastEncodeStatus("Encode >{}< Finished".format(i))
if config["mv"]:
shutil.move(i, config["mtd"])
elif config["del"]:
@ -107,10 +107,10 @@ def run(name):
_count = 0
_count_error = 0
while True:
if api.isLive:
if api.isLive and not forceNotBroadcasting:
if d is None:
d = datetime.strftime(datetime.now(), "%Y_%m_%d")
if not t.is_alive():
if not t.is_alive() and not forceStopDownload:
_count_error += 1
_preT = api.playlist
t = threading.Thread(target=download, args=(_preT,))

73
static/index.html Normal file
View File

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>录播</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<style type="text/css">
td{
border: solid 1px lightgrey;
}
</style>
</head>
<body>
<div>
<h1>基本信息</h1>
<table>
<tr>
<td>主播名</td>
<td><span id="broadcaster"></span></td>
</tr>
<tr>
<td>是否正在直播</td>
<td><span id="isBroadcasting"></span></td>
</tr>
<tr>
<td>直播视频流地址</td>
<td><span id="streamUrl"></span></td>
</tr>
<tr>
<td>信息更新时间</td>
<td><span id="updateTime"></span></td>
</tr>
</table>
<h1>特殊设置</h1>
<table>
<tr>
<td>是否设置强制认为不直播</td>
<td><span id="forceNotBroadcasting"></span></td>
</tr>
<tr>
<td>是否设置强制不下载</td>
<td><span id="forceStopDownload"></span></td>
</tr>
</table>
<hr/>
<h1>当前状态</h1>
<table>
<tr>
<td>下载日志</td>
<td><span id="download"></span></td>
</tr>
<tr>
<td>转码日志</td>
<td><span id="encode"></span></td>
</tr>
<tr>
<td>上传日志</td>
<td><span id="upload"></span></td>
</tr>
<tr>
<td>错误日志</td>
<td><span id="error"></span></td>
</tr>
<tr>
<td>操作日志</td>
<td><span id="operation"></span></td>
</tr>
</table>
<hr/>
</div>
</body>
<script src="index.js"></script>
</html>

45
static/index.js Normal file
View File

@ -0,0 +1,45 @@
function update(){
$.ajax(
"/stats",
{
success: function (res){
$("#broadcaster").text(res.data.broadcast.broadcaster)
$("#isBroadcasting").text(res.data.broadcast.isBroadcasting)
$("#streamUrl").text(res.data.broadcast.streamUrl)
$("#forceNotBroadcasting").text(res.data.config.forceNotBroadcasting)
$("#forceStopDownload").text(res.data.config.forceStopDownload)
$("#updateTime").text(res.data.broadcast.updateTime)
$("#download").html(function(){
var ret = ""
res.data.download.reverse().forEach(function(obj){
ret += "<tr><td>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#encode").html(function(){
var ret = ""
res.data.encode.reverse().forEach(function(obj){
ret += "<tr><td>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#upload").html(function(){
var ret = ""
res.data.upload.reverse().forEach(function(obj){
ret += "<tr><td>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
$("#error").html(function(){
var ret = ""
res.data.error.reverse().forEach(function(obj){
ret += "<tr><td>" + obj.datetime + "</td><td>" + obj.message + "</td></tr>"
})
return "<table>" + ret + "</table>"
})
}
}
)
}
update()
setInterval(update,10000)

25
templates/files.html Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>文件</title>
<style>
td{
border: solid 1px lightgray;
}
</style>
</head>
<body>
<h1>所有录像文件</h1>
<table>
<tr>
<td>文件名</td><td>文件大小</td><td>链接</td>
</tr>
{%for i in files %}
<tr>
<td>{{i.name}}</td><td>{{i.size}}</td><td><a href="/files/download/{{i.name}}">下载文件</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>