Skip to content

Commit

Permalink
Allow custom VLC command and custom audio device in streaming
Browse files Browse the repository at this point in the history
  • Loading branch information
Krisjanis Veinbahs committed Mar 10, 2022
1 parent ac36c6b commit 85efcad
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 6 deletions.
10 changes: 10 additions & 0 deletions client/src/service/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,8 @@ async def agent_hardware_camera(
heartbeat_seconds: int,
is_stream_existing: bool,
stream_url_str: Optional[str],
video_vlc: Optional[str],
audio_device: Optional[str],
video_device: Optional[str],
video_width: Optional[int],
video_height: Optional[int],
Expand Down Expand Up @@ -810,6 +812,8 @@ async def quick_run(
def parsed_video_config(
is_stream_existing: bool,
stream_url_str: Optional[str],
video_vlc: Optional[str],
audio_device: Optional[str],
video_device: Optional[str],
video_width: Optional[int],
video_height: Optional[int],
Expand All @@ -830,6 +834,8 @@ def parsed_video_config(
if video_width is None: return Err(GenericClientError("Video stream width is required"))
if video_height is None: return Err(GenericClientError("Video stream height is required"))
return Ok(VLCStreamConfig.build(
video_vlc,
audio_device,
video_device_result.value,
video_width,
video_height,
Expand All @@ -846,6 +852,8 @@ async def agent_hardware_camera(
heartbeat_seconds: int,
is_stream_existing: bool,
stream_url_str: Optional[str],
video_vlc: Optional[str],
audio_device: Optional[str],
video_device: Optional[str],
video_width: Optional[int],
video_height: Optional[int],
Expand All @@ -866,6 +874,8 @@ async def agent_hardware_camera(
video_config_result = CLI.parsed_video_config(
is_stream_existing,
stream_url_str,
video_vlc,
audio_device,
video_device,
video_width,
video_height,
Expand Down
16 changes: 16 additions & 0 deletions client/src/service/click.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@
help='URL for an existing video source (if is_stream_existing), e.g. http://localhost:8081/webcam.ogg'
)
# Video stream (non-existing)
STREAM_VLC_OPTION = click.option(
'--stream-vlc', '-r', "video_vlc", show_envvar=True,
type=str, envvar=f"{ENV_PREFIX}_STREAM_VLC", required=False,
help='VLC command to be used, e.g. "vlc" or "vlc-pi"'
)
STREAM_AUDIO_DEVICE_OPTION = click.option(
'--stream-audio', '-z', "audio_device", show_envvar=True,
type=str, envvar=f"{ENV_PREFIX}_STREAM_AUDIO_DEVICE", required=False,
help='VLC slave audio device to be used, e.g. "alsa://"'
)
STREAM_DEVICE_PATH_OPTION = click.option(
'--stream-device', '-d', "video_device", show_envvar=True,
type=str, envvar=f"{ENV_PREFIX}_STREAM_DEVICE_PATH", required=False,
Expand Down Expand Up @@ -618,6 +628,8 @@ async def exec():
@HEARTBEAT_SECONDS_OPTION
@IS_STREAM_EXISTING_OPTION
@STREAM_URL_OPTION
@STREAM_VLC_OPTION
@STREAM_AUDIO_DEVICE_OPTION
@STREAM_DEVICE_PATH_OPTION
@STREAM_WIDTH_OPTION
@STREAM_HEIGHT_OPTION
Expand All @@ -632,6 +644,8 @@ def agent_hardware_video(
heartbeat_seconds: int,
is_stream_existing: bool,
stream_url_str: Optional[str],
video_vlc: Optional[str],
audio_device: Optional[str],
video_device: Optional[str],
video_width: Optional[int],
video_height: Optional[int],
Expand All @@ -650,6 +664,8 @@ async def exec():
heartbeat_seconds,
is_stream_existing,
stream_url_str,
video_vlc,
audio_device,
video_device,
video_width,
video_height,
Expand Down
10 changes: 8 additions & 2 deletions client/src/service/managed_video_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import aiohttp
from aiohttp import ClientSession, ClientResponse
from result import Result, Err, Ok

from src.domain.death import Death
from src.domain.dip_client_error import DIPClientError, GenericClientError
from src.domain.existing_file_path import ExistingFilePath
from src.service.managed_url import ManagedURL, ManagedURLBuildError
Expand Down Expand Up @@ -35,6 +33,8 @@ def to_url(self) -> Result[ManagedURL, ManagedURLBuildError]:

@dataclass
class VLCStreamConfig(VideoStreamConfig):
video_vlc: str
audio_device: str
video_device: ExistingFilePath
video_width: int
video_height: int
Expand All @@ -45,6 +45,8 @@ class VLCStreamConfig(VideoStreamConfig):

@staticmethod
def build(
video_vlc: Optional[str],
audio_device: Optional[str],
video_device: ExistingFilePath,
video_width: int,
video_height: int,
Expand All @@ -54,6 +56,8 @@ def build(
port: Optional[int]
):
return VLCStreamConfig(
video_vlc if video_vlc is not None else "vlc",
audio_device if audio_device is not None else "",
video_device,
video_width,
video_height,
Expand All @@ -69,6 +73,8 @@ def vlc_shell_args(self: 'VLCStreamConfig') -> List[str]:
"bash",
"-c",
f"{vlc_script_path} "
f"-r \"{self.video_vlc}\" "
f"-z \"{self.audio_device}\" "
f"-d \"{self.video_device.value}\" "
f"-w \"{self.video_width}\" "
f"-h \"{self.video_height}\" "
Expand Down
23 changes: 19 additions & 4 deletions client/src/static/vlc/stream.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ set -euo pipefail
# Script usage help
usage() {
echo 'Streams a V4L2 video stream on a given TCP socket using VLC'
echo 'usage: -d /dev/video0 -w 1280 -h 720 -v 50 -s 44100 -a 50 -p 8081'
echo 'usage: -r "vlc" -z "alsa://" -d /dev/video0 -w 1280 -h 720 -v 50 -s 44100 -a 50 -p 8081'
echo ' -r VLC command'
echo ' -z V4L2 audio device'
echo ' -d V4L2 device path'
echo ' -w Video width in pixels'
echo ' -h Video height in pixels'
Expand All @@ -18,15 +20,19 @@ usage() {

# Flag parsing sourced from: https://google.github.io/styleguide/shellguide.html
# also from: https://stackoverflow.com/a/11279500/10806216
vlc_command="vlc"
audio_device="alsa://"
video_device="/dev/video0"
video_width="1280"
video_height="720"
video_buffer_size="50"
audio_sample_rate="44100"
audio_buffer_size="50"
port="8081"
while getopts 'd:w:h:v:s:a:p:' flag; do
while getopts 'r:z:d:w:h:v:s:a:p:' flag; do
case "${flag}" in
r) vlc_command="${OPTARG}" ;;
z) audio_device="${OPTARG}" ;;
d) video_device="${OPTARG}" ;;
w) video_width="${OPTARG}" ;;
h) video_height="${OPTARG}" ;;
Expand All @@ -41,7 +47,17 @@ done
# Print usage
usage

# Audio device argument is optional
audio_device_argument=""
if [[ $audio_device ]]
then
audio_device_argument=":input-slave=${audio_device}"
fi


# Env dump
echo "Audio device: ${audio_device}"
echo "Audio device argument: ${audio_device_argument}"
echo "Video device: ${video_device}"
echo "Video width: ${video_width}"
echo "Video height: ${video_height}"
Expand All @@ -52,8 +68,7 @@ echo "Port: ${port}"

# Start video stream
echo "Starting video stream..."
vlc v4l2:// \
:input-slave=alsa:// \
"${vlc_command}" v4l2:// ${audio_device_argument} \
:v4l2-standard=1 \
:v4l2-dev=${video_device} \
:v4l2-width=${video_width} \
Expand Down

0 comments on commit 85efcad

Please sign in to comment.