ytptube/app/player/Segments.py
2024-02-02 18:07:24 +03:00

105 lines
3.3 KiB
Python

import hashlib
import logging
import os
import subprocess
import tempfile
from Utils import calcDownloadPath
LOG = logging.getLogger('segments')
class Segments:
segment_duration: int
segment_index: int
vconvert: bool
aconvert: bool
def __init__(self, segment_index: int, segment_duration: float, vconvert: bool, aconvert: bool):
self.segment_duration = float(segment_duration)
self.segment_index = int(segment_index)
self.vconvert = bool(vconvert)
self.aconvert = bool(aconvert)
async def stream(self, download_path: str, file: str) -> bytes:
realFile: str = calcDownloadPath(basePath=download_path, folder=file, createPath=False)
if not os.path.exists(realFile):
raise Exception(f"File {realFile} does not exist.")
tmpDir: str = tempfile.gettempdir()
tmpFile = os.path.join(tmpDir, f'ytptube_stream.{hashlib.md5(realFile.encode("utf-8")).hexdigest()}')
if not os.path.exists(tmpFile):
os.symlink(realFile, tmpFile)
if self.segment_index == 0:
startTime: float = '{:.6f}'.format(0)
else:
startTime: float = '{:.6f}'.format((self.segment_duration * self.segment_index))
ffmpegCmd = []
ffmpegCmd.append('ffmpeg')
ffmpegCmd.append('-xerror')
ffmpegCmd.append('-hide_banner')
ffmpegCmd.append('-loglevel')
ffmpegCmd.append('error')
ffmpegCmd.append('-ss')
ffmpegCmd.append(str(startTime if startTime else '0.00000'))
ffmpegCmd.append('-t')
ffmpegCmd.append(str('{:.6f}'.format(self.segment_duration)))
ffmpegCmd.append('-copyts')
ffmpegCmd.append('-i')
ffmpegCmd.append(f'file:{tmpFile}')
ffmpegCmd.append('-map_metadata')
ffmpegCmd.append('-1')
ffmpegCmd.append('-pix_fmt')
ffmpegCmd.append('yuv420p')
ffmpegCmd.append('-g')
ffmpegCmd.append('52')
ffmpegCmd.append('-map')
ffmpegCmd.append('0:v:0')
ffmpegCmd.append('-strict')
ffmpegCmd.append('-2')
ffmpegCmd.append('-codec:v')
ffmpegCmd.append('libx264' if self.vconvert else 'copy')
if self.vconvert:
ffmpegCmd.append('-crf')
ffmpegCmd.append('23')
ffmpegCmd.append('-preset:v')
ffmpegCmd.append('fast')
ffmpegCmd.append('-level')
ffmpegCmd.append('4.1')
ffmpegCmd.append('-profile:v')
ffmpegCmd.append('baseline')
# audio section.
ffmpegCmd.append('-map')
ffmpegCmd.append('0:a:0')
ffmpegCmd.append('-codec:a')
ffmpegCmd.append('aac' if self.aconvert else 'copy')
if self.aconvert:
ffmpegCmd.append('-b:a')
ffmpegCmd.append('192k')
ffmpegCmd.append('-ar')
ffmpegCmd.append('22050')
ffmpegCmd.append('-ac')
ffmpegCmd.append('2')
ffmpegCmd.append('-sn')
ffmpegCmd.append('-muxdelay')
ffmpegCmd.append('0')
ffmpegCmd.append('-f')
ffmpegCmd.append('mpegts')
ffmpegCmd.append('pipe:1')
LOG.debug(f'Streaming {realFile} segment {self.segment_index}.' + ' '.join(ffmpegCmd))
proc = subprocess.run(ffmpegCmd, stdout=subprocess.PIPE)
return proc.stdout