formatting
This commit is contained in:
parent
1fbe833d39
commit
26aa401bfe
|
@ -80,12 +80,10 @@ class AudioStreamer(threading.Thread):
|
||||||
return self.silence, "[NOTHING PLAYING]"
|
return self.silence, "[NOTHING PLAYING]"
|
||||||
|
|
||||||
def stream_queued_audio(self):
|
def stream_queued_audio(self):
|
||||||
|
|
||||||
stream = None
|
stream = None
|
||||||
title = None
|
title = None
|
||||||
next_stream = None
|
next_stream = None
|
||||||
next_title = None
|
next_title = None
|
||||||
buffer = b''
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
stream, title = (next_stream, next_title) if next_stream else self.queued_audio_source()
|
stream, title = (next_stream, next_title) if next_stream else self.queued_audio_source()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from dataclasses import dataclass
|
||||||
from io import BufferedReader
|
from io import BufferedReader
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
import ffmpeg
|
import ffmpeg
|
||||||
|
|
||||||
|
@ -24,8 +24,9 @@ class FrameAlignedStream:
|
||||||
>>> for segment in stream:
|
>>> for segment in stream:
|
||||||
...
|
...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
source: BufferedReader
|
source: BufferedReader
|
||||||
chunk_size: int = 1024
|
chunk_size: int = 1024
|
||||||
bit_rate: int = 192000
|
bit_rate: int = 192000
|
||||||
sample_rate: int = 44100
|
sample_rate: int = 44100
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ class FrameAlignedStream:
|
||||||
|
|
||||||
# step through the source a byte at a time and look for the frame sync.
|
# step through the source a byte at a time and look for the frame sync.
|
||||||
header = None
|
header = None
|
||||||
buffer = b''
|
buffer = b""
|
||||||
while not header:
|
while not header:
|
||||||
buffer += self.source.read(4 - len(buffer))
|
buffer += self.source.read(4 - len(buffer))
|
||||||
if len(buffer) != 4:
|
if len(buffer) != 4:
|
||||||
|
@ -84,11 +85,11 @@ class FrameAlignedStream:
|
||||||
Generate approximately chunk_size segments of audio data by iterating over the
|
Generate approximately chunk_size segments of audio data by iterating over the
|
||||||
frames, buffering them, and then yielding several as a single bytes object.
|
frames, buffering them, and then yielding several as a single bytes object.
|
||||||
"""
|
"""
|
||||||
buf = b''
|
buf = b""
|
||||||
for frame in self.frames:
|
for frame in self.frames:
|
||||||
if len(buf) >= self.chunk_size:
|
if len(buf) >= self.chunk_size:
|
||||||
yield buf
|
yield buf
|
||||||
buf = b''
|
buf = b""
|
||||||
if not frame:
|
if not frame:
|
||||||
break
|
break
|
||||||
buf += frame
|
buf += frame
|
||||||
|
@ -102,28 +103,27 @@ class FrameAlignedStream:
|
||||||
"""
|
"""
|
||||||
ffmpeg_args = (
|
ffmpeg_args = (
|
||||||
ffmpeg.input(str(infile))
|
ffmpeg.input(str(infile))
|
||||||
.output("pipe:",
|
.output(
|
||||||
map='a',
|
"pipe:",
|
||||||
format="mp3",
|
map="a",
|
||||||
|
format="mp3",
|
||||||
# no ID3 headers -- saves having to decode them later
|
# no ID3 headers -- saves having to decode them later
|
||||||
write_xing=0,
|
write_xing=0,
|
||||||
id3v2_version=0,
|
id3v2_version=0,
|
||||||
|
# force sasmple and bit rates
|
||||||
# force sasmple and bit rates
|
**{
|
||||||
**{
|
"b:a": kwargs.get("bit_rate", cls.bit_rate),
|
||||||
'b:a': kwargs.get('bit_rate', cls.bit_rate),
|
"ar": kwargs.get("sample_rate", cls.sample_rate),
|
||||||
'ar': kwargs.get('sample_rate', cls.sample_rate),
|
},
|
||||||
})
|
)
|
||||||
.global_args("-hide_banner", "-vn")
|
.global_args("-hide_banner", "-vn")
|
||||||
.compile()
|
.compile()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Force close STDIN to prevent ffmpeg from trying to read from it. silly ffmpeg.
|
# Force close STDIN to prevent ffmpeg from trying to read from it. silly ffmpeg.
|
||||||
proc = subprocess.Popen(ffmpeg_args,
|
proc = subprocess.Popen(
|
||||||
bufsize=kwargs.get('chunk_size', cls.chunk_size),
|
ffmpeg_args, bufsize=kwargs.get("chunk_size", cls.chunk_size), stdout=subprocess.PIPE, stdin=subprocess.PIPE
|
||||||
stdout=subprocess.PIPE,
|
)
|
||||||
stdin=subprocess.PIPE)
|
|
||||||
proc.stdin.close()
|
proc.stdin.close()
|
||||||
logger.debug(f"Spawned ffmpeg (PID {proc.pid}) with args {ffmpeg_args = }")
|
logger.debug(f"Spawned ffmpeg (PID {proc.pid}) with args {ffmpeg_args = }")
|
||||||
return cls(proc.stdout, **kwargs)
|
return cls(proc.stdout, **kwargs)
|
||||||
|
|
|
@ -10,9 +10,8 @@ from croaker import playlist, transcoder
|
||||||
def mock_mp3decoder(monkeypatch):
|
def mock_mp3decoder(monkeypatch):
|
||||||
def read(stream):
|
def read(stream):
|
||||||
return stream.read()
|
return stream.read()
|
||||||
monkeypatch.setattr(transcoder, 'MP3Decoder', MagicMock(**{
|
|
||||||
'__enter__.return_value.read': read
|
monkeypatch.setattr(transcoder, "MP3Decoder", MagicMock(**{"__enter__.return_value.read": read}))
|
||||||
}))
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail
|
@pytest.mark.xfail
|
||||||
|
|
Loading…
Reference in New Issue
Block a user