fix: fix fps display

This commit is contained in:
acgnhik 2022-06-08 19:43:23 +08:00
parent 04aae19735
commit 1bd49c310f
11 changed files with 62 additions and 67 deletions

View File

@ -1,6 +1,7 @@
import asyncio
import logging
from enum import Enum
from threading import Lock
from typing import Set
import aiofiles
@ -45,7 +46,7 @@ class CoverDownloader(StreamRecorderEventListener, SwitchableMixin):
super().__init__()
self._live = live
self._stream_recorder = stream_recorder
self._lock: asyncio.Lock = asyncio.Lock()
self._lock: Lock = Lock()
self._sha1_set: Set[str] = set()
self.save_cover = save_cover
self.cover_save_strategy = cover_save_strategy
@ -60,7 +61,7 @@ class CoverDownloader(StreamRecorderEventListener, SwitchableMixin):
logger.debug('Disabled cover downloader')
async def on_video_file_completed(self, video_path: str) -> None:
async with self._lock:
with self._lock:
if not self.save_cover:
return
task = asyncio.create_task(self._save_cover(video_path))

View File

@ -1,31 +1,31 @@
import html
import asyncio
import html
import logging
from contextlib import suppress
from threading import Lock
from typing import Iterator, List, Optional
from tenacity import (
AsyncRetrying,
stop_after_attempt,
retry_if_not_exception_type,
)
from tenacity import AsyncRetrying, retry_if_not_exception_type, stop_after_attempt
from .. import __version__, __prog__, __github__
from .danmaku_receiver import DanmakuReceiver, DanmuMsg
from .stream_recorder import StreamRecorder, StreamRecorderEventListener
from .statistics import Statistics
from .. import __github__, __prog__, __version__
from ..bili.live import Live
from ..exception import exception_callback, submit_exception
from ..event.event_emitter import EventListener, EventEmitter
from ..path import danmaku_path
from ..core.models import GiftSendMsg, GuardBuyMsg, SuperChatMsg
from ..danmaku.models import (
Metadata, Danmu, GiftSendRecord, GuardBuyRecord, SuperChatRecord
)
from ..danmaku.io import DanmakuWriter
from ..utils.mixins import SwitchableMixin
from ..danmaku.models import (
Danmu,
GiftSendRecord,
GuardBuyRecord,
Metadata,
SuperChatRecord,
)
from ..event.event_emitter import EventEmitter, EventListener
from ..exception import exception_callback, submit_exception
from ..logging.room_id import aio_task_with_room_id
from ..path import danmaku_path
from ..utils.mixins import SwitchableMixin
from .danmaku_receiver import DanmakuReceiver, DanmuMsg
from .statistics import Statistics
from .stream_recorder import StreamRecorder, StreamRecorderEventListener
__all__ = 'DanmakuDumper', 'DanmakuDumperEventListener'
@ -70,7 +70,7 @@ class DanmakuDumper(
self.record_guard_buy = record_guard_buy
self.record_super_chat = record_super_chat
self._lock: asyncio.Lock = asyncio.Lock()
self._lock: Lock = Lock()
self._path: Optional[str] = None
self._files: List[str] = []
self._statistics = Statistics(interval=60)
@ -115,14 +115,14 @@ class DanmakuDumper(
async def on_video_file_created(
self, video_path: str, record_start_time: int
) -> None:
async with self._lock:
with self._lock:
self._path = danmaku_path(video_path)
self._record_start_time = record_start_time
self._files.append(self._path)
self._start_dumping()
async def on_video_file_completed(self, video_path: str) -> None:
async with self._lock:
with self._lock:
await self._stop_dumping()
self._path = None
@ -154,9 +154,7 @@ class DanmakuDumper(
await writer.write_metadata(self._make_metadata())
async for attempt in AsyncRetrying(
retry=retry_if_not_exception_type((
asyncio.CancelledError
)),
retry=retry_if_not_exception_type((asyncio.CancelledError)),
stop=stop_after_attempt(3),
):
with attempt:
@ -181,24 +179,17 @@ class DanmakuDumper(
if not self.record_gift_send:
continue
record = self._make_gift_send_record(msg)
if (
not self.record_free_gifts and
record.is_free_gift()
):
if not self.record_free_gifts and record.is_free_gift():
continue
await writer.write_gift_send_record(record)
elif isinstance(msg, GuardBuyMsg):
if not self.record_guard_buy:
continue
await writer.write_guard_buy_record(
self._make_guard_buy_record(msg)
)
await writer.write_guard_buy_record(self._make_guard_buy_record(msg))
elif isinstance(msg, SuperChatMsg):
if not self.record_super_chat:
continue
await writer.write_super_chat_record(
self._make_super_chat_record(msg)
)
await writer.write_super_chat_record(self._make_super_chat_record(msg))
else:
logger.warning('Unsupported message type:', repr(msg))

View File

@ -1,25 +1,21 @@
import json
import asyncio
import json
import logging
from contextlib import suppress
from threading import Lock
import aiofiles
from aiofiles.threadpool.text import AsyncTextIOWrapper
from tenacity import (
AsyncRetrying,
stop_after_attempt,
retry_if_not_exception_type,
)
from tenacity import AsyncRetrying, retry_if_not_exception_type, stop_after_attempt
from .raw_danmaku_receiver import RawDanmakuReceiver
from .stream_recorder import StreamRecorder, StreamRecorderEventListener
from ..bili.live import Live
from ..event.event_emitter import EventEmitter, EventListener
from ..exception import exception_callback, submit_exception
from ..event.event_emitter import EventListener, EventEmitter
from ..logging.room_id import aio_task_with_room_id
from ..path import raw_danmaku_path
from ..utils.mixins import SwitchableMixin
from ..logging.room_id import aio_task_with_room_id
from .raw_danmaku_receiver import RawDanmakuReceiver
from .stream_recorder import StreamRecorder, StreamRecorderEventListener
__all__ = 'RawDanmakuDumper', 'RawDanmakuDumperEventListener'
@ -50,8 +46,7 @@ class RawDanmakuDumper(
self._live = live # @aio_task_with_room_id
self._stream_recorder = stream_recorder
self._receiver = danmaku_receiver
self._lock: asyncio.Lock = asyncio.Lock()
self._lock: Lock = Lock()
def _do_enable(self) -> None:
self._stream_recorder.add_listener(self)
@ -64,12 +59,12 @@ class RawDanmakuDumper(
async def on_video_file_created(
self, video_path: str, record_start_time: int
) -> None:
async with self._lock:
with self._lock:
self._path = raw_danmaku_path(video_path)
self._start_dumping()
async def on_video_file_completed(self, video_path: str) -> None:
async with self._lock:
with self._lock:
await self._stop_dumping()
def _start_dumping(self) -> None:
@ -96,9 +91,7 @@ class RawDanmakuDumper(
await self._emit('raw_danmaku_file_created', self._path)
async for attempt in AsyncRetrying(
retry=retry_if_not_exception_type((
asyncio.CancelledError
)),
retry=retry_if_not_exception_type((asyncio.CancelledError)),
stop=stop_after_attempt(3),
):
with attempt:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,6 +10,6 @@
<body>
<app-root></app-root>
<noscript>Please enable JavaScript to continue using this application.</noscript>
<script src="runtime.8ba8344712d0946d.js" type="module"></script><script src="polyfills.4b08448aee19bb22.js" type="module"></script><script src="main.b9234f0840c7101a.js" type="module"></script>
<script src="runtime.4a35817fcd0b6f13.js" type="module"></script><script src="polyfills.4b08448aee19bb22.js" type="module"></script><script src="main.411b4a979eb179f8.js" type="module"></script>
</body></html>

View File

@ -1,6 +1,6 @@
{
"configVersion": 1,
"timestamp": 1653113686866,
"timestamp": 1654687612398,
"index": "/index.html",
"assetGroups": [
{
@ -13,16 +13,16 @@
"urls": [
"/103.5b5d2a6e5a8a7479.js",
"/146.92e3b29c4c754544.js",
"/183.b24b23ce9efcd26f.js",
"/45.c90c3cea2bf1a66e.js",
"/474.7f6529972e383566.js",
"/66.31f5b9ae46ae9005.js",
"/869.0ab6b8a3f466df77.js",
"/common.858f777e9296e6f2.js",
"/index.html",
"/main.b9234f0840c7101a.js",
"/main.411b4a979eb179f8.js",
"/manifest.webmanifest",
"/polyfills.4b08448aee19bb22.js",
"/runtime.8ba8344712d0946d.js",
"/runtime.4a35817fcd0b6f13.js",
"/styles.1f581691b230dc4d.css"
],
"patterns": []
@ -1636,10 +1636,10 @@
"hashTable": {
"/103.5b5d2a6e5a8a7479.js": "cc0240f217015b6d4ddcc14f31fcc42e1c1c282a",
"/146.92e3b29c4c754544.js": "3824de681dd1f982ea69a065cdf54d7a1e781f4d",
"/183.b24b23ce9efcd26f.js": "e0f6f72a02aaf70fde1de9f8b2f9e0eea908c5c5",
"/45.c90c3cea2bf1a66e.js": "e5bfb8cf3803593e6b8ea14c90b3d3cb6a066764",
"/474.7f6529972e383566.js": "1c74b5c6379705a3110c99767f97feddc42a0d54",
"/66.31f5b9ae46ae9005.js": "cc22d2582d8e4c2a83e089d5a1ec32619e439ccd",
"/869.0ab6b8a3f466df77.js": "fd3e32d78790ec916177aa38b49ca32bfe62d0d4",
"/assets/animal/panda.js": "fec2868bb3053dd2da45f96bbcb86d5116ed72b1",
"/assets/animal/panda.svg": "bebd302cdc601e0ead3a6d2710acf8753f3d83b1",
"/assets/fill/.gitkeep": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
@ -3234,11 +3234,11 @@
"/assets/twotone/warning.js": "fb2d7ea232f3a99bf8f080dbc94c65699232ac01",
"/assets/twotone/warning.svg": "8c7a2d3e765a2e7dd58ac674870c6655cecb0068",
"/common.858f777e9296e6f2.js": "b68ca68e1e214a2537d96935c23410126cc564dd",
"/index.html": "da07776fe6f05347b1b8360f61b81c59734dcc54",
"/main.b9234f0840c7101a.js": "c8c7b588c070b957a2659f62d6a77de284aa2233",
"/index.html": "c756360e1bb95916aafb1adbc94838f09028ce0e",
"/main.411b4a979eb179f8.js": "4c5e77b0589a77410f84441d0877c1d18cb1357f",
"/manifest.webmanifest": "62c1cb8c5ad2af551a956b97013ab55ce77dd586",
"/polyfills.4b08448aee19bb22.js": "8e73f2d42cc13ca353cea5c886d930bd6da08d0d",
"/runtime.8ba8344712d0946d.js": "264d0e7e1e88dd1a4383d73d401f5ccd51e40eb7",
"/runtime.4a35817fcd0b6f13.js": "5c1f850331e4731999af02f1067b589ef3e99d3c",
"/styles.1f581691b230dc4d.css": "6f5befbbad57c2b2e80aae855139744b8010d150"
},
"navigationUrls": [

View File

@ -1 +1 @@
(()=>{"use strict";var e,v={},m={};function r(e){var i=m[e];if(void 0!==i)return i.exports;var t=m[e]={exports:{}};return v[e].call(t.exports,t,t.exports,r),t.exports}r.m=v,e=[],r.O=(i,t,o,f)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,o,f]=e[n],c=!0,l=0;l<t.length;l++)(!1&f||a>=f)&&Object.keys(r.O).every(b=>r.O[b](t[l]))?t.splice(l--,1):(c=!1,f<a&&(a=f));if(c){e.splice(n--,1);var d=o();void 0!==d&&(i=d)}}return i}f=f||0;for(var n=e.length;n>0&&e[n-1][2]>f;n--)e[n]=e[n-1];e[n]=[t,o,f]},r.n=e=>{var i=e&&e.__esModule?()=>e.default:()=>e;return r.d(i,{a:i}),i},r.d=(e,i)=>{for(var t in i)r.o(i,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:i[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((i,t)=>(r.f[t](e,i),i),[])),r.u=e=>(592===e?"common":e)+"."+{45:"c90c3cea2bf1a66e",66:"31f5b9ae46ae9005",103:"5b5d2a6e5a8a7479",146:"92e3b29c4c754544",474:"7f6529972e383566",592:"858f777e9296e6f2",869:"0ab6b8a3f466df77"}[e]+".js",r.miniCssF=e=>{},r.o=(e,i)=>Object.prototype.hasOwnProperty.call(e,i),(()=>{var e={},i="blrec:";r.l=(t,o,f,n)=>{if(e[t])e[t].push(o);else{var a,c;if(void 0!==f)for(var l=document.getElementsByTagName("script"),d=0;d<l.length;d++){var u=l[d];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==i+f){a=u;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",i+f),a.src=r.tu(t)),e[t]=[o];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var _=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),_&&_.forEach(h=>h(b)),g)return g(b)},p=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),c&&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=i=>(void 0===e&&(e={createScriptURL:t=>t},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(i))})(),r.p="",(()=>{var e={666:0};r.f.j=(o,f)=>{var n=r.o(e,o)?e[o]:void 0;if(0!==n)if(n)f.push(n[2]);else if(666!=o){var a=new Promise((u,s)=>n=e[o]=[u,s]);f.push(n[2]=a);var c=r.p+r.u(o),l=new Error;r.l(c,u=>{if(r.o(e,o)&&(0!==(n=e[o])&&(e[o]=void 0),n)){var s=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;l.message="Loading chunk "+o+" failed.\n("+s+": "+p+")",l.name="ChunkLoadError",l.type=s,l.request=p,n[1](l)}},"chunk-"+o,o)}else e[o]=0},r.O.j=o=>0===e[o];var i=(o,f)=>{var l,d,[n,a,c]=f,u=0;if(n.some(p=>0!==e[p])){for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(c)var s=c(r)}for(o&&o(f);u<n.length;u++)r.o(e,d=n[u])&&e[d]&&e[d][0](),e[n[u]]=0;return r.O(s)},t=self.webpackChunkblrec=self.webpackChunkblrec||[];t.forEach(i.bind(null,0)),t.push=i.bind(null,t.push.bind(t))})()})();
(()=>{"use strict";var e,v={},m={};function r(e){var i=m[e];if(void 0!==i)return i.exports;var t=m[e]={exports:{}};return v[e].call(t.exports,t,t.exports,r),t.exports}r.m=v,e=[],r.O=(i,t,o,f)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,o,f]=e[n],c=!0,l=0;l<t.length;l++)(!1&f||a>=f)&&Object.keys(r.O).every(b=>r.O[b](t[l]))?t.splice(l--,1):(c=!1,f<a&&(a=f));if(c){e.splice(n--,1);var d=o();void 0!==d&&(i=d)}}return i}f=f||0;for(var n=e.length;n>0&&e[n-1][2]>f;n--)e[n]=e[n-1];e[n]=[t,o,f]},r.n=e=>{var i=e&&e.__esModule?()=>e.default:()=>e;return r.d(i,{a:i}),i},r.d=(e,i)=>{for(var t in i)r.o(i,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:i[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((i,t)=>(r.f[t](e,i),i),[])),r.u=e=>(592===e?"common":e)+"."+{45:"c90c3cea2bf1a66e",66:"31f5b9ae46ae9005",103:"5b5d2a6e5a8a7479",146:"92e3b29c4c754544",183:"b24b23ce9efcd26f",474:"7f6529972e383566",592:"858f777e9296e6f2"}[e]+".js",r.miniCssF=e=>{},r.o=(e,i)=>Object.prototype.hasOwnProperty.call(e,i),(()=>{var e={},i="blrec:";r.l=(t,o,f,n)=>{if(e[t])e[t].push(o);else{var a,c;if(void 0!==f)for(var l=document.getElementsByTagName("script"),d=0;d<l.length;d++){var u=l[d];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==i+f){a=u;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",i+f),a.src=r.tu(t)),e[t]=[o];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var _=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),_&&_.forEach(h=>h(b)),g)return g(b)},p=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),c&&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=i=>(void 0===e&&(e={createScriptURL:t=>t},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(i))})(),r.p="",(()=>{var e={666:0};r.f.j=(o,f)=>{var n=r.o(e,o)?e[o]:void 0;if(0!==n)if(n)f.push(n[2]);else if(666!=o){var a=new Promise((u,s)=>n=e[o]=[u,s]);f.push(n[2]=a);var c=r.p+r.u(o),l=new Error;r.l(c,u=>{if(r.o(e,o)&&(0!==(n=e[o])&&(e[o]=void 0),n)){var s=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;l.message="Loading chunk "+o+" failed.\n("+s+": "+p+")",l.name="ChunkLoadError",l.type=s,l.request=p,n[1](l)}},"chunk-"+o,o)}else e[o]=0},r.O.j=o=>0===e[o];var i=(o,f)=>{var l,d,[n,a,c]=f,u=0;if(n.some(p=>0!==e[p])){for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(c)var s=c(r)}for(o&&o(f);u<n.length;u++)r.o(e,d=n[u])&&e[d]&&e[d][0](),e[n[u]]=0;return r.O(s)},t=self.webpackChunkblrec=self.webpackChunkblrec||[];t.forEach(i.bind(null,0)),t.push=i.bind(null,t.push.bind(t))})()})();

View File

@ -24,7 +24,7 @@
<span>
{{ profile.streams[0]?.width }}x{{ profile.streams[0]?.height }}
</span>
<span> {{ profile.streams[0]?.r_frame_rate!.split("/")[0] }} fps</span>
<span> {{ fps }} fps</span>
<!-- <span
*ngIf="
profile.streams[0]?.bit_rate && profile.streams[0]?.bit_rate !== '1'

View File

@ -40,6 +40,16 @@ export class InfoPanelComponent implements OnInit, OnDestroy {
private taskService: TaskService
) {}
get fps(): string {
const avgFrameRate: string | undefined =
this.profile?.streams![0]?.avg_frame_rate;
if (avgFrameRate) {
return eval(avgFrameRate).toString();
} else {
return 'N/A';
}
}
ngOnInit(): void {
this.syncData();
}