some changes
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
"""Tests for cht.stream.ffmpeg — pipeline construction and execution."""
|
||||
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
import pytest
|
||||
@@ -12,76 +10,43 @@ import ffmpeg as ffmpeg_lib
|
||||
from cht.stream import ffmpeg as ff
|
||||
|
||||
|
||||
class TestReceiveAndSegment:
|
||||
class TestReceiveAndRecord:
|
||||
def test_compiles_to_valid_cmd(self, tmp_path):
|
||||
node = ff.receive_and_segment(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path, segment_duration=30
|
||||
node = ff.receive_and_record(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path / "recording.ts"
|
||||
)
|
||||
cmd = node.compile()
|
||||
cmd_str = " ".join(str(c) for c in cmd)
|
||||
|
||||
assert cmd[0] == "ffmpeg"
|
||||
assert "tcp://0.0.0.0:4444?listen" in cmd_str
|
||||
assert "segment" in cmd_str
|
||||
assert str(tmp_path / "segment_%04d.ts") in cmd_str
|
||||
assert "recording.ts" in cmd_str
|
||||
|
||||
def test_input_has_low_latency_flags(self, tmp_path):
|
||||
node = ff.receive_and_segment("tcp://0.0.0.0:4444?listen", tmp_path)
|
||||
node = ff.receive_and_record(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path / "rec.ts"
|
||||
)
|
||||
cmd_str = " ".join(str(c) for c in node.compile())
|
||||
assert "nobuffer" in cmd_str
|
||||
assert "low_delay" in cmd_str
|
||||
|
||||
def test_copy_codec(self, tmp_path):
|
||||
node = ff.receive_and_segment("tcp://0.0.0.0:4444?listen", tmp_path)
|
||||
node = ff.receive_and_record(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path / "rec.ts"
|
||||
)
|
||||
assert "copy" in node.compile()
|
||||
|
||||
def test_has_global_args(self, tmp_path):
|
||||
node = ff.receive_and_segment("tcp://0.0.0.0:4444?listen", tmp_path)
|
||||
cmd = node.compile()
|
||||
assert "-hide_banner" in cmd
|
||||
|
||||
|
||||
class TestReceiveAndSegmentWithMonitor:
|
||||
def test_creates_fifo(self, tmp_path):
|
||||
fifo = tmp_path / "monitor.pipe"
|
||||
ff.receive_and_segment_with_monitor(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path, fifo
|
||||
)
|
||||
assert fifo.exists()
|
||||
|
||||
def test_does_not_recreate_existing_fifo(self, tmp_path):
|
||||
fifo = tmp_path / "monitor.pipe"
|
||||
os.mkfifo(str(fifo))
|
||||
inode_before = fifo.stat().st_ino
|
||||
ff.receive_and_segment_with_monitor(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path, fifo
|
||||
)
|
||||
assert fifo.stat().st_ino == inode_before
|
||||
|
||||
def test_has_two_outputs(self, tmp_path):
|
||||
fifo = tmp_path / "monitor.pipe"
|
||||
node = ff.receive_and_segment_with_monitor(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path, fifo
|
||||
)
|
||||
cmd_str = " ".join(str(c) for c in node.compile())
|
||||
assert "segment_%04d.ts" in cmd_str
|
||||
assert "monitor.pipe" in cmd_str
|
||||
|
||||
def test_both_outputs_use_copy(self, tmp_path):
|
||||
fifo = tmp_path / "monitor.pipe"
|
||||
node = ff.receive_and_segment_with_monitor(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path, fifo
|
||||
)
|
||||
cmd = node.compile()
|
||||
assert cmd.count("copy") >= 2
|
||||
|
||||
def test_has_global_args(self, tmp_path):
|
||||
fifo = tmp_path / "monitor.pipe"
|
||||
node = ff.receive_and_segment_with_monitor(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path, fifo
|
||||
node = ff.receive_and_record(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path / "rec.ts"
|
||||
)
|
||||
assert "-hide_banner" in node.compile()
|
||||
|
||||
def test_mpegts_format(self, tmp_path):
|
||||
node = ff.receive_and_record(
|
||||
"tcp://0.0.0.0:4444?listen", tmp_path / "rec.ts"
|
||||
)
|
||||
assert "mpegts" in node.compile()
|
||||
|
||||
|
||||
class TestExtractSceneFrames:
|
||||
def test_compiles_select_filter(self, tmp_path):
|
||||
@@ -113,32 +78,12 @@ class TestExtractSceneFrames:
|
||||
assert stderr == "err"
|
||||
|
||||
|
||||
class TestExtractAudioPcm:
|
||||
def test_compiles_audio_extraction(self, tmp_path):
|
||||
node = ff.extract_audio_pcm(tmp_path / "test.ts")
|
||||
cmd_str = " ".join(str(c) for c in node.compile())
|
||||
assert "pcm_s16le" in cmd_str
|
||||
assert "16000" in cmd_str
|
||||
assert "pipe:" in cmd_str
|
||||
assert "wav" in cmd_str
|
||||
|
||||
def test_has_global_args(self, tmp_path):
|
||||
node = ff.extract_audio_pcm(tmp_path / "test.ts")
|
||||
assert "-hide_banner" in node.compile()
|
||||
|
||||
|
||||
class TestRunAsync:
|
||||
@patch("ffmpeg.run_async")
|
||||
def test_delegates_to_ffmpeg_python(self, mock_run_async, tmp_path):
|
||||
node = ffmpeg_lib.input("test").output("out")
|
||||
ff.run_async(node)
|
||||
# ffmpeg-python's run_async is called on the node
|
||||
# Our function calls node.run_async() which is the bound method
|
||||
|
||||
@patch("ffmpeg.run_async")
|
||||
def test_passes_pipe_flags(self, mock_run_async, tmp_path):
|
||||
node = ffmpeg_lib.input("test").output("out")
|
||||
ff.run_async(node, pipe_stdout=True, pipe_stderr=True)
|
||||
def test_compiles_valid_command(self, tmp_path):
|
||||
node = ff.receive_and_record("tcp://0.0.0.0:4444?listen", tmp_path / "rec.ts")
|
||||
cmd = node.compile()
|
||||
assert cmd[0] == "ffmpeg"
|
||||
assert "tcp://0.0.0.0:4444?listen" in " ".join(cmd)
|
||||
|
||||
|
||||
class TestStopProc:
|
||||
|
||||
Reference in New Issue
Block a user