mirror of
https://github.com/acgnhiki/blrec.git
synced 2024-12-27 17:10:18 +08:00
release: v1.0.5
This commit is contained in:
parent
4f1d6bef27
commit
6b61738d09
@ -1,5 +1,11 @@
|
||||
# 更新日志
|
||||
|
||||
## 1.0.5
|
||||
|
||||
- 修复路径模板设置的模板变量显示不完整
|
||||
- 修复主机绑定不是 localhost 自动打开浏览器访问出错
|
||||
- 其它一些重构调整
|
||||
|
||||
## 1.0.4
|
||||
|
||||
- 兼容 SRT 推流
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
__version__ = '1.0.4'
|
||||
__prog__ = 'blrec'
|
||||
__version__ = '1.0.5'
|
||||
__github__ = 'https://github.com/acgnhiki/blrec'
|
||||
|
@ -5,6 +5,13 @@ import json
|
||||
from typing import Dict, List, Optional, cast
|
||||
|
||||
import aiohttp
|
||||
from tenacity import (
|
||||
retry,
|
||||
wait_exponential,
|
||||
stop_after_delay,
|
||||
retry_if_exception_type,
|
||||
)
|
||||
|
||||
|
||||
from .api import WebApi
|
||||
from .models import LiveStatus, RoomInfo, UserInfo
|
||||
@ -32,6 +39,9 @@ class Live:
|
||||
self._cookie = cookie
|
||||
self._html_page_url = f'https://live.bilibili.com/{room_id}'
|
||||
|
||||
self._room_info: RoomInfo
|
||||
self._user_info: UserInfo
|
||||
|
||||
@property
|
||||
def user_agent(self) -> str:
|
||||
return self._user_agent
|
||||
@ -103,9 +113,25 @@ class Live:
|
||||
async def update_info(self) -> None:
|
||||
await asyncio.wait([self.update_user_info(), self.update_room_info()])
|
||||
|
||||
@retry(
|
||||
reraise=True,
|
||||
retry=retry_if_exception_type((
|
||||
asyncio.TimeoutError, aiohttp.ClientError,
|
||||
)),
|
||||
wait=wait_exponential(max=10),
|
||||
stop=stop_after_delay(60),
|
||||
)
|
||||
async def update_user_info(self) -> None:
|
||||
self._user_info = await self.get_user_info(self._room_info.uid)
|
||||
|
||||
@retry(
|
||||
reraise=True,
|
||||
retry=retry_if_exception_type((
|
||||
asyncio.TimeoutError, aiohttp.ClientError,
|
||||
)),
|
||||
wait=wait_exponential(max=10),
|
||||
stop=stop_after_delay(60),
|
||||
)
|
||||
async def update_room_info(self) -> None:
|
||||
self._room_info = await self.get_room_info()
|
||||
|
||||
|
@ -103,7 +103,11 @@ class LiveMonitor(
|
||||
))
|
||||
|
||||
await self._live.update_info()
|
||||
assert self._live.room_info.live_status == current_status
|
||||
if (s := self._live.room_info.live_status) != current_status:
|
||||
logger.warning(
|
||||
'Updated live status {} is inconsistent with '
|
||||
'current live status {}'.format(s.name, current_status.name)
|
||||
)
|
||||
|
||||
await self._emit(
|
||||
'live_status_changed', current_status, self._previous_status
|
||||
|
@ -44,7 +44,7 @@ def cli_main(
|
||||
'-o',
|
||||
help='path of directory to save files (overwrite setting)'
|
||||
),
|
||||
host: str = typer.Option('127.0.0.1', help='webapp host bind'),
|
||||
host: str = typer.Option('localhost', help='webapp host bind'),
|
||||
port: int = typer.Option(2233, help='webapp port bind'),
|
||||
open: bool = typer.Option(False, help='open webapp in default browser'),
|
||||
key_file: Optional[str] = typer.Option(None, help='SSL key file'),
|
||||
@ -60,7 +60,7 @@ def cli_main(
|
||||
os.environ['out_dir'] = out_dir
|
||||
|
||||
if open:
|
||||
typer.launch(f'http://{host}:{port}')
|
||||
typer.launch(f'http://localhost:{port}')
|
||||
|
||||
logging_config = deepcopy(LOGGING_CONFIG)
|
||||
logging_config['handlers']['default']['stream'] = TqdmOutputStream
|
||||
|
@ -5,7 +5,7 @@ from contextlib import suppress
|
||||
from typing import Iterator, List
|
||||
|
||||
|
||||
from .. import __version__, __prog__
|
||||
from .. import __version__, __prog__, __github__
|
||||
from .danmaku_receiver import DanmakuReceiver, DanmuMsg
|
||||
from .stream_recorder import StreamRecorder, StreamRecorderEventListener
|
||||
from .statistics import StatisticsCalculator
|
||||
@ -131,7 +131,7 @@ class DanmakuDumper(StreamRecorderEventListener, SwitchableMixin):
|
||||
parent_area=self._live.room_info.parent_area_name,
|
||||
live_start_time=self._live.room_info.live_start_time,
|
||||
record_start_time=self._record_start_time,
|
||||
recorder=f'{__prog__} {__version__}',
|
||||
recorder=f'{__prog__} v{__version__} {__github__}',
|
||||
)
|
||||
|
||||
def _make_danmu(self, msg: DanmuMsg) -> Danmu:
|
||||
|
@ -31,7 +31,7 @@ from tenacity import (
|
||||
TryAgain,
|
||||
)
|
||||
|
||||
from .. import __version__, __prog__
|
||||
from .. import __version__, __prog__, __github__
|
||||
from .retry import wait_exponential_for_same_exceptions, before_sleep_log
|
||||
from .statistics import StatisticsCalculator
|
||||
from ..event.event_emitter import EventListener, EventEmitter
|
||||
@ -365,7 +365,6 @@ class StreamRecorder(
|
||||
)
|
||||
|
||||
def _make_metadata(self) -> Dict[str, Any]:
|
||||
github_url = 'https://github.com/acgnhiki/blrec'
|
||||
live_start_time = datetime.fromtimestamp(
|
||||
self._live.room_info.live_start_time, timezone(timedelta(hours=8))
|
||||
)
|
||||
@ -381,7 +380,7 @@ B站直播录像
|
||||
分区:{self._live.room_info.parent_area_name} - {self._live.room_info.area_name}
|
||||
房间号:{self._live.room_info.room_id}
|
||||
开播时间:{live_start_time}
|
||||
录制程序:{__prog__} v{__version__} {github_url}''',
|
||||
录制程序:{__prog__} v{__version__} {__github__}''',
|
||||
'description': OrderedDict({
|
||||
'UserId': str(self._live.user_info.uid),
|
||||
'UserName': self._live.user_info.name,
|
||||
@ -390,7 +389,7 @@ B站直播录像
|
||||
'Area': self._live.room_info.area_name,
|
||||
'ParentArea': self._live.room_info.parent_area_name,
|
||||
'LiveStartTime': str(live_start_time),
|
||||
'Recorder': f'{__prog__} v{__version__} {github_url}',
|
||||
'Recorder': f'{__prog__} v{__version__} {__github__}',
|
||||
})
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -10,6 +10,6 @@
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
||||
<script src="runtime.9c55e9c0a6d0459b5e96.js" defer></script><script src="polyfills.a427f031f0f7196ffda1.js" defer></script><script src="main.22f06d53efe81d9df3a8.js" defer></script>
|
||||
<script src="runtime.4c79c38349615627b59b.js" defer></script><script src="polyfills.a427f031f0f7196ffda1.js" defer></script><script src="main.22f06d53efe81d9df3a8.js" defer></script>
|
||||
|
||||
</body></html>
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"configVersion": 1,
|
||||
"timestamp": 1628613033243,
|
||||
"timestamp": 1631943201826,
|
||||
"index": "/index.html",
|
||||
"assetGroups": [
|
||||
{
|
||||
@ -12,7 +12,7 @@
|
||||
},
|
||||
"urls": [
|
||||
"/198.20d927ba29c55516dd2e.js",
|
||||
"/51.560338ef5c3689b822f9.js",
|
||||
"/51.275a97b45765f0cf1623.js",
|
||||
"/659.4923e830b3feb2abcce2.js",
|
||||
"/80.78cb9b41766e5c57d657.js",
|
||||
"/954.05cbcc74da25eb3ef2a9.js",
|
||||
@ -21,7 +21,7 @@
|
||||
"/main.22f06d53efe81d9df3a8.js",
|
||||
"/manifest.webmanifest",
|
||||
"/polyfills.a427f031f0f7196ffda1.js",
|
||||
"/runtime.9c55e9c0a6d0459b5e96.js",
|
||||
"/runtime.4c79c38349615627b59b.js",
|
||||
"/styles.09c5ed83b6748436b293.css"
|
||||
],
|
||||
"patterns": []
|
||||
@ -1632,7 +1632,7 @@
|
||||
"dataGroups": [],
|
||||
"hashTable": {
|
||||
"/198.20d927ba29c55516dd2e.js": "93bf87b6cc89e0a67c508c5c232d50d73c659057",
|
||||
"/51.560338ef5c3689b822f9.js": "c31964ceca4ec203c3a60de2e75667ac4bfd5528",
|
||||
"/51.275a97b45765f0cf1623.js": "0bcd069e622a8682773ea72e425c191b391509cb",
|
||||
"/659.4923e830b3feb2abcce2.js": "e74b2b9b53cd108ab7e91f765ca0926c42b3fd1f",
|
||||
"/80.78cb9b41766e5c57d657.js": "ae52bd0e9cf819763e1f843ead3fb5adc10afffa",
|
||||
"/954.05cbcc74da25eb3ef2a9.js": "38c071c377d3a6d98902e679340d6a609996b717",
|
||||
@ -3228,11 +3228,11 @@
|
||||
"/assets/twotone/warning.js": "fb2d7ea232f3a99bf8f080dbc94c65699232ac01",
|
||||
"/assets/twotone/warning.svg": "8c7a2d3e765a2e7dd58ac674870c6655cecb0068",
|
||||
"/common.fa68e1b34f0baff6ccad.js": "8e62b9aa49dde6486f74c6c94b97054743f1cc1b",
|
||||
"/index.html": "cdd5b6a2184b9d03b7afeea5e2721c4c63d6772a",
|
||||
"/index.html": "98bb17017bf0130fb96ffae491a76787731b918c",
|
||||
"/main.22f06d53efe81d9df3a8.js": "edb0ba67f76a4a734eaf210655790ca4926f45a6",
|
||||
"/manifest.webmanifest": "0c4534b4c868d756691b1b4372cecb2efce47c6d",
|
||||
"/polyfills.a427f031f0f7196ffda1.js": "3e4560be48cd30e30bcbf51ca131a37d8c224fdc",
|
||||
"/runtime.9c55e9c0a6d0459b5e96.js": "514cd785b41aa8c04d9925e4b5313d48d7404612",
|
||||
"/runtime.4c79c38349615627b59b.js": "f6de29446d188dd27541769e856ced4fa651e670",
|
||||
"/styles.09c5ed83b6748436b293.css": "c08136817a63dadd53de8cb2df2d56ba95e5905a"
|
||||
},
|
||||
"navigationUrls": [
|
||||
|
@ -1 +1 @@
|
||||
(()=>{"use strict";var e,v={},m={};function r(e){var n=m[e];if(void 0!==n)return n.exports;var t=m[e]={exports:{}};return v[e].call(t.exports,t,t.exports,r),t.exports}r.m=v,e=[],r.O=(n,t,i,o)=>{if(!t){var a=1/0;for(f=0;f<e.length;f++){for(var[t,i,o]=e[f],d=!0,l=0;l<t.length;l++)(!1&o||a>=o)&&Object.keys(r.O).every(p=>r.O[p](t[l]))?t.splice(l--,1):(d=!1,o<a&&(a=o));if(d){e.splice(f--,1);var c=i();void 0!==c&&(n=c)}}return n}o=o||0;for(var f=e.length;f>0&&e[f-1][2]>o;f--)e[f]=e[f-1];e[f]=[t,i,o]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>(592===e?"common":e)+"."+{51:"560338ef5c3689b822f9",80:"78cb9b41766e5c57d657",198:"20d927ba29c55516dd2e",592:"fa68e1b34f0baff6ccad",659:"4923e830b3feb2abcce2",954:"05cbcc74da25eb3ef2a9"}[e]+".js",r.miniCssF=e=>"styles.09c5ed83b6748436b293.css",r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="blrec:";r.l=(t,i,o,f)=>{if(e[t])e[t].push(i);else{var a,d;if(void 0!==o)for(var l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var u=l[c];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==n+o){a=u;break}}a||(d=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+o),a.src=r.tu(t)),e[t]=[i];var s=(g,p)=>{a.onerror=a.onload=null,clearTimeout(b);var _=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),_&&_.forEach(h=>h(p)),g)return g(p)},b=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),d&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;r.tu=n=>(void 0===e&&(e={createScriptURL:t=>t},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(n))})(),r.p="",(()=>{var e={666:0};r.f.j=(i,o)=>{var f=r.o(e,i)?e[i]:void 0;if(0!==f)if(f)o.push(f[2]);else if(666!=i){var a=new Promise((u,s)=>f=e[i]=[u,s]);o.push(f[2]=a);var d=r.p+r.u(i),l=new Error;r.l(d,u=>{if(r.o(e,i)&&(0!==(f=e[i])&&(e[i]=void 0),f)){var s=u&&("load"===u.type?"missing":u.type),b=u&&u.target&&u.target.src;l.message="Loading chunk "+i+" failed.\n("+s+": "+b+")",l.name="ChunkLoadError",l.type=s,l.request=b,f[1](l)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var n=(i,o)=>{var l,c,[f,a,d]=o,u=0;for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(d)var s=d(r);for(i&&i(o);u<f.length;u++)r.o(e,c=f[u])&&e[c]&&e[c][0](),e[f[u]]=0;return r.O(s)},t=self.webpackChunkblrec=self.webpackChunkblrec||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})();
|
||||
(()=>{"use strict";var e,v={},m={};function r(e){var n=m[e];if(void 0!==n)return n.exports;var t=m[e]={exports:{}};return v[e].call(t.exports,t,t.exports,r),t.exports}r.m=v,e=[],r.O=(n,t,i,o)=>{if(!t){var a=1/0;for(f=0;f<e.length;f++){for(var[t,i,o]=e[f],d=!0,l=0;l<t.length;l++)(!1&o||a>=o)&&Object.keys(r.O).every(p=>r.O[p](t[l]))?t.splice(l--,1):(d=!1,o<a&&(a=o));if(d){e.splice(f--,1);var c=i();void 0!==c&&(n=c)}}return n}o=o||0;for(var f=e.length;f>0&&e[f-1][2]>o;f--)e[f]=e[f-1];e[f]=[t,i,o]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>(592===e?"common":e)+"."+{51:"275a97b45765f0cf1623",80:"78cb9b41766e5c57d657",198:"20d927ba29c55516dd2e",592:"fa68e1b34f0baff6ccad",659:"4923e830b3feb2abcce2",954:"05cbcc74da25eb3ef2a9"}[e]+".js",r.miniCssF=e=>"styles.09c5ed83b6748436b293.css",r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="blrec:";r.l=(t,i,o,f)=>{if(e[t])e[t].push(i);else{var a,d;if(void 0!==o)for(var l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var u=l[c];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==n+o){a=u;break}}a||(d=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+o),a.src=r.tu(t)),e[t]=[i];var s=(g,p)=>{a.onerror=a.onload=null,clearTimeout(b);var _=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),_&&_.forEach(h=>h(p)),g)return g(p)},b=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),d&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e;r.tu=n=>(void 0===e&&(e={createScriptURL:t=>t},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(n))})(),r.p="",(()=>{var e={666:0};r.f.j=(i,o)=>{var f=r.o(e,i)?e[i]:void 0;if(0!==f)if(f)o.push(f[2]);else if(666!=i){var a=new Promise((u,s)=>f=e[i]=[u,s]);o.push(f[2]=a);var d=r.p+r.u(i),l=new Error;r.l(d,u=>{if(r.o(e,i)&&(0!==(f=e[i])&&(e[i]=void 0),f)){var s=u&&("load"===u.type?"missing":u.type),b=u&&u.target&&u.target.src;l.message="Loading chunk "+i+" failed.\n("+s+": "+b+")",l.name="ChunkLoadError",l.type=s,l.request=b,f[1](l)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var n=(i,o)=>{var l,c,[f,a,d]=o,u=0;for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(d)var s=d(r);for(i&&i(o);u<f.length;u++)r.o(e,c=f[u])&&e[c]&&e[c][0](),e[f[u]]=0;return r.O(s)},t=self.webpackChunkblrec=self.webpackChunkblrec||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})();
|
@ -129,10 +129,15 @@ def is_metadata_tag(tag: FlvTag) -> TypeGuard[ScriptTag]:
|
||||
|
||||
|
||||
def is_data_tag(tag: FlvTag) -> TypeGuard[Union[AudioTag, VideoTag]]:
|
||||
return (
|
||||
(is_video_tag(tag) and tag.is_avc_nalu()) or
|
||||
(is_audio_tag(tag) and tag.is_aac_raw())
|
||||
)
|
||||
return is_audio_data_tag(tag) or is_video_data_tag(tag)
|
||||
|
||||
|
||||
def is_audio_data_tag(tag: FlvTag) -> TypeGuard[AudioTag]:
|
||||
return is_audio_tag(tag) and tag.is_aac_raw()
|
||||
|
||||
|
||||
def is_video_data_tag(tag: FlvTag) -> TypeGuard[VideoTag]:
|
||||
return is_video_tag(tag) and tag.is_avc_nalu()
|
||||
|
||||
|
||||
def is_sequence_header(tag: FlvTag) -> TypeGuard[Union[AudioTag, VideoTag]]:
|
||||
|
@ -687,11 +687,15 @@ class FlvReaderWithTimestampFix(FlvReader):
|
||||
self._update_parameters(tag)
|
||||
return tag
|
||||
|
||||
if not is_data_tag(tag):
|
||||
return tag
|
||||
|
||||
if self._is_ts_rebounded(tag):
|
||||
self._update_delta(tag)
|
||||
logger.warning(
|
||||
f'Timestamp rebounded, updated delta: {self._delta}\n'
|
||||
f'last tag: {self._last_tag}\n'
|
||||
f'last video tag: {self._last_video_tag}\n'
|
||||
f'last audio tag: {self._last_audio_tag}\n'
|
||||
f'current tag: {tag}'
|
||||
)
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
<nz-table
|
||||
#table
|
||||
[nzData]="pathTemplateVariables"
|
||||
[nzPageSize]="11"
|
||||
[nzShowPagination]="false"
|
||||
[nzSize]="'small'"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user