mirror of
https://github.com/acgnhiki/blrec.git
synced 2025-01-14 04:10:06 +08:00
release: 1.6.0-alpha
This commit is contained in:
parent
93d93888e4
commit
5c9887a2a8
@ -1,5 +1,9 @@
|
||||
# 更新日志
|
||||
|
||||
## 1.6.0-alpha
|
||||
|
||||
- REST API 支持获取正在录制的 flv 文件的路径和元数据
|
||||
|
||||
## 1.5.0
|
||||
|
||||
- 支持设置日志文件存放位置
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
__prog__ = 'blrec'
|
||||
__version__ = '1.5.0'
|
||||
__version__ = '1.6.0-alpha'
|
||||
__github__ = 'https://github.com/acgnhiki/blrec'
|
||||
|
@ -7,6 +7,7 @@ import attr
|
||||
import psutil
|
||||
|
||||
from . import __prog__, __version__
|
||||
from .flv.data_analyser import MetaData
|
||||
from .disk_space import SpaceMonitor, SpaceReclaimer
|
||||
from .bili.helpers import ensure_room_id
|
||||
from .task import (
|
||||
@ -201,6 +202,9 @@ class Application:
|
||||
def get_task_param(self, room_id: int) -> TaskParam:
|
||||
return self._task_manager.get_task_param(room_id)
|
||||
|
||||
def get_task_metadata(self, room_id: int) -> Optional[MetaData]:
|
||||
return self._task_manager.get_task_metadata(room_id)
|
||||
|
||||
def get_task_video_file_details(
|
||||
self, room_id: int
|
||||
) -> Iterator[VideoFileDetail]:
|
||||
|
@ -14,6 +14,7 @@ from .raw_danmaku_receiver import RawDanmakuReceiver
|
||||
from .raw_danmaku_dumper import RawDanmakuDumper, RawDanmakuDumperEventListener
|
||||
from .stream_recorder import StreamRecorder, StreamRecorderEventListener
|
||||
from ..event.event_emitter import EventListener, EventEmitter
|
||||
from ..flv.data_analyser import MetaData
|
||||
from ..bili.live import Live
|
||||
from ..bili.models import RoomInfo
|
||||
from ..bili.danmaku_client import DanmakuClient
|
||||
@ -274,6 +275,14 @@ class Recorder(
|
||||
def duration_limit(self, value: int) -> None:
|
||||
self._stream_recorder.duration_limit = value
|
||||
|
||||
@property
|
||||
def recording_path(self) -> Optional[str]:
|
||||
return self._stream_recorder.recording_path
|
||||
|
||||
@property
|
||||
def metadata(self) -> Optional[MetaData]:
|
||||
return self._stream_recorder.metadata
|
||||
|
||||
async def _do_start(self) -> None:
|
||||
self._live_monitor.add_listener(self)
|
||||
self._danmaku_dumper.add_listener(self)
|
||||
|
@ -38,6 +38,7 @@ from .statistics import StatisticsCalculator
|
||||
from ..event.event_emitter import EventListener, EventEmitter
|
||||
from ..bili.live import Live
|
||||
from ..bili.typing import QualityNumber
|
||||
from ..flv.data_analyser import MetaData
|
||||
from ..flv.stream_processor import StreamProcessor, BaseOutputFileManager
|
||||
from ..utils.mixins import AsyncCooperationMix, AsyncStoppableMixin
|
||||
from ..path import escape_path
|
||||
@ -186,6 +187,13 @@ class StreamRecorder(
|
||||
def recording_path(self) -> Optional[str]:
|
||||
return self._file_manager.curr_path
|
||||
|
||||
@property
|
||||
def metadata(self) -> Optional[MetaData]:
|
||||
if self._stream_processor is not None:
|
||||
return self._stream_processor.metadata
|
||||
else:
|
||||
return None
|
||||
|
||||
def has_file(self) -> bool:
|
||||
return self._file_manager.has_file()
|
||||
|
||||
|
@ -14,7 +14,7 @@ from .models import (
|
||||
from .common import Resolution, is_audio_tag, is_script_tag, is_video_tag
|
||||
|
||||
|
||||
__all__ = 'DataAnalyser',
|
||||
__all__ = 'DataAnalyser', 'MetaData', 'KeyFrames'
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, slots=True, frozen=True, kw_only=True)
|
||||
|
@ -14,7 +14,7 @@ from rx.subject import Subject
|
||||
from rx.core import Observable
|
||||
|
||||
from .models import FlvHeader, FlvTag, ScriptTag, VideoTag, AudioTag
|
||||
from .data_analyser import DataAnalyser
|
||||
from .data_analyser import DataAnalyser, MetaData
|
||||
from .stream_cutter import StreamCutter
|
||||
from .limit_checker import LimitChecker
|
||||
from .parameters_checker import ParametersChecker
|
||||
@ -117,6 +117,16 @@ class StreamProcessor:
|
||||
for point in self._join_points:
|
||||
yield point
|
||||
|
||||
@property
|
||||
def metadata(self) -> Optional[MetaData]:
|
||||
if not self._analyse_data:
|
||||
return None
|
||||
try:
|
||||
return self._data_analyser.make_metadata()
|
||||
except Exception as e:
|
||||
logger.debug(f'Failed to make metadata data, due to: {repr(e)}')
|
||||
return None
|
||||
|
||||
@property
|
||||
def size_updates(self) -> Observable:
|
||||
return self._size_updates
|
||||
|
@ -1,5 +1,4 @@
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import asyncio
|
||||
from typing import Optional, TYPE_CHECKING, cast
|
||||
|
||||
|
@ -29,6 +29,7 @@ class TaskStatus:
|
||||
danmu_count: int # Number of Danmu in total
|
||||
danmu_rate: float # Number of Danmu per minutes
|
||||
real_quality_number: QualityNumber
|
||||
recording_path: Optional[str] = None
|
||||
postprocessor_status: PostprocessorStatus = PostprocessorStatus.WAITING
|
||||
postprocessing_path: Optional[str] = None
|
||||
postprocessing_progress: Optional[Progress] = None
|
||||
|
@ -21,6 +21,7 @@ from ..core import Recorder
|
||||
from ..postprocess import Postprocessor, PostprocessorStatus, DeleteStrategy
|
||||
from ..postprocess.remuxer import RemuxProgress
|
||||
from ..flv.metadata_injector import InjectProgress
|
||||
from ..flv.data_analyser import MetaData
|
||||
from ..event.event_submitters import (
|
||||
LiveEventSubmitter, RecorderEventSubmitter, PostprocessorEventSubmitter
|
||||
)
|
||||
@ -132,6 +133,7 @@ class RecordTask:
|
||||
danmu_count=self._recorder.danmu_count,
|
||||
danmu_rate=self._recorder.danmu_rate,
|
||||
real_quality_number=self._recorder.real_quality_number,
|
||||
recording_path=self.recording_path,
|
||||
postprocessor_status=self._postprocessor.status,
|
||||
postprocessing_path=self._postprocessor.postprocessing_path,
|
||||
postprocessing_progress=(
|
||||
@ -349,6 +351,14 @@ class RecordTask:
|
||||
def duration_limit(self, value: int) -> None:
|
||||
self._recorder.duration_limit = value
|
||||
|
||||
@property
|
||||
def recording_path(self) -> Optional[str]:
|
||||
return self._recorder.recording_path
|
||||
|
||||
@property
|
||||
def metadata(self) -> Optional[MetaData]:
|
||||
return self._recorder.metadata
|
||||
|
||||
@property
|
||||
def remux_to_mp4(self) -> bool:
|
||||
return self._postprocessor.remux_to_mp4
|
||||
|
@ -1,10 +1,11 @@
|
||||
from __future__ import annotations
|
||||
import asyncio
|
||||
from typing import Dict, Iterator, TYPE_CHECKING
|
||||
from typing import Dict, Iterator, Optional, TYPE_CHECKING
|
||||
|
||||
|
||||
from .task import RecordTask
|
||||
from .models import TaskData, TaskParam, VideoFileDetail, DanmakuFileDetail
|
||||
from ..flv.data_analyser import MetaData
|
||||
from ..exception import NotFoundError
|
||||
if TYPE_CHECKING:
|
||||
from ..setting import SettingsManager
|
||||
@ -154,6 +155,10 @@ class RecordTaskManager:
|
||||
task = self._get_task(room_id)
|
||||
return self._make_task_param(task)
|
||||
|
||||
def get_task_metadata(self, room_id: int) -> Optional[MetaData]:
|
||||
task = self._get_task(room_id)
|
||||
return task.metadata
|
||||
|
||||
def get_task_video_file_details(
|
||||
self, room_id: int
|
||||
) -> Iterator[VideoFileDetail]:
|
||||
|
@ -53,6 +53,17 @@ async def get_task_param(room_id: int) -> Dict[str, Any]:
|
||||
return attr.asdict(app.get_task_param(room_id))
|
||||
|
||||
|
||||
@router.get(
|
||||
'/{room_id}/metadata',
|
||||
responses={**not_found_responses},
|
||||
)
|
||||
async def get_task_metadata(room_id: int) -> Dict[str, Any]:
|
||||
metadata = app.get_task_metadata(room_id)
|
||||
if not metadata:
|
||||
return {}
|
||||
return attr.asdict(metadata)
|
||||
|
||||
|
||||
@router.get(
|
||||
'/{room_id}/videos',
|
||||
responses={**not_found_responses},
|
||||
|
Loading…
Reference in New Issue
Block a user