From bed6b5f87ac80dc9206c539623dc25a853bd140b Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Mon, 11 Jan 2016 08:03:44 -0800 Subject: added log file to ignore list --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad69f2a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +feed.log -- cgit v1.2.3 From 8fecf681ea9c68ba1e4a97a90e85a0d850f3f9ae Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Mon, 11 Jan 2016 22:36:18 -0800 Subject: semi-working bridge between webcam mic and default mic --- prepare-videochat.sh | 151 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 29 deletions(-) diff --git a/prepare-videochat.sh b/prepare-videochat.sh index 341a8e9..38a36d2 100755 --- a/prepare-videochat.sh +++ b/prepare-videochat.sh @@ -92,6 +92,11 @@ else FLIP_METHOD=none fi +GST_FLIP="! videoflip method=\"$FLIP_METHOD\" " +if [ $FLIP_METHOD = 'none' ]; then + GST_FLIP="" +fi + ### CONFIGURATION # If your "adb" is not in your $PATH, set the full path to it here. @@ -113,8 +118,6 @@ WIFI_IP=192.168.2.140 # Port on which IP Webcam is listening PORT=8080 -# GStreamer debug string (see gst-launch manpage) -GST_DEBUG=souphttpsrc:0,videoflip:0,ffmpegcolorspace:0,v4l2sink:0,pulse:0 ### FUNCTIONS @@ -156,7 +159,7 @@ url_reachable() { if ! can_run curl && can_run apt-get; then # Some versions of Ubuntu do not have curl by default (Arch # has it in its core, so we don't need to check that case) - sudo apt-get install curl + sudo apt-get install -y curl fi curl -sI "$1" >/dev/null } @@ -174,13 +177,48 @@ start_iw_server() { sleep 2s } +if can_run lsb_release; then + DIST=`lsb_release -i | awk -F: '{print $2}'` + RELEASE=`lsb_release -r | awk -F: '{print $2}'` +elif [ -f /etc/debian_version ] ; then + DIST="Debian" + RELEASE=`perl -ne 'chomp; if(m:(jessie|testing|sid):){print "8.0"}elsif(m:[\d\.]+:){print}else{print "0.0"}' < /etc/debian_version` +fi + +GST_VER="0.10" +GST_CONVERTER="ffmpegcolorspace" +GST_MIMETYPE="video/x-raw-yuv" +GST_FORMAT="format=(fourcc)YV12" + +GST_0_10_MIMETYPE=$GST_MIMETYPE +GST_0_10_FORMAT=$GST_FORMAT + +if [ $DIST = "Debian" -a `echo "$RELEASE >= 8.0" | bc` -eq 1 ] ||\ + [ $DIST = "Ubuntu" -a `echo "$RELEASE >= 14.04" | bc` -eq 1 ] +then + GST_VER="1.0" + GST_CONVERTER="videoconvert" + GST_MIMETYPE="video/x-raw" + GST_FORMAT="format=YV12" +fi + +# GStreamer debug string (see gst-launch manpage) +GST_DEBUG=souphttpsrc:0,videoflip:0,$GST_CONVERTER:0,v4l2sink:0,pulse:0 + ### MAIN BODY # Check if the user has v4l2loopback if ! has_kernel_module v4l2loopback; then - info "The v4l2loopback kernel module is not installed or could not be loaded. I will try to install the kernel module using your distro's package manager. If that doesn't work, please install v4l2loopback manually from github.com/umlaeute/v4l2loopback." - if can_run apt-get; then - sudo apt-get install python-apport v4l2loopback-dkms + info "The v4l2loopback kernel module is not installed or could not be loaded. Attempting to install the kernel module using your distro's package manager." + if [ $DIST = "Debian" ] || [ $DIST = "Ubuntu" ]; then + V4L2LOOPBACK_PKGS="v4l2loopback-dkms" + if [ $DIST = "Ubuntu" ]; then + V4L2LOOPBACK_PKGS="${V4L2LOOPBACK_PKGS} python-apport" + fi + sudo apt-get -y install $V4L2LOOPBACK_PKGS + if [ $? != 0 ]; then + info "Installation failed. Please install v4l2loopback manually from github.com/umlaeute/v4l2loopback." + fi elif can_run yaourt; then yaourt -S v4l2loopback-git fi @@ -192,12 +230,21 @@ if ! has_kernel_module v4l2loopback; then fi fi +# check if the user has the pulse gst plugin installed +if [ ! -f /usr/lib/*/gstreamer-$GST_VER/libgstpulse.so ]; then + if [ $DIST = "Debian" ] || [ $DIST = "Ubuntu" ]; then + sudo apt-get install -y gstreamer${GST_VER}-pulseaudio + elif can_run yaourt; then + echo "we should figure out what package supplies this" + fi +fi + # Use the first "v4l2 loopback" device as the webcam: this should help # when loading v4l2loopback on a system that already has a regular # webcam. if ! can_run v4l2-ctl; then if can_run apt-get; then - sudo apt-get install v4l-utils + sudo apt-get install -y v4l-utils elif can_run pacman; then sudo pacman -S v4l-utils fi @@ -241,38 +288,67 @@ while ! iw_server_is_started; do info "The IP Webcam video feed is not reachable at $VIDEO_URL. Please open IP Webcam in your phone and start the server." done +SINK_NAME="ipwebcam" # Load null-sink if needed -if !(pactl list sinks | grep -q module-null-sink); then - pactl load-module module-null-sink +if !(pactl list sinks | grep -q $SINK_NAME); then + pactl load-module module-null-sink sink_name="$SINK_NAME" sink_properties="device.description='IP\ Webcam'" fi -NULL_SINK=$(LC_ALL=C pactl list sinks | \ - sed -n -e '/Name:/h; /module-null-sink/{x; s/\s*Name:\s*//g; p; q}' ) +SINK_ID=$(pactl list sinks | sed -n -e "/Owner Module:/h; /$SINK_NAME.monitor/{x; s/\s*Owner Module:\s*//g; p; q}") + +#DUPLEX_SINK_NAME="ipwebcam_mic" +#if !(pactl list sinks | grep -q $DUPLEX_SINK_NAME); then +# pactl load-module module-null-sink sink_name="$DUPLEX_SINK_NAME" sink_properties="device.description='IP\ Webcam\ and\ Mic\ MUX',filter.want=echo-cancel" +#fi +#DUPLEX_SINK_ID=$(pactl list sinks | sed -n -e "/Owner Module:/h; /$DUPLEX_SINK_NAME.monitor/{x; s/\s*Owner Module:\s*//g; p; q}") + + +#if !(pactl list modules | grep -q "source=${SINK_NAME}.monitor sink=${DUPLEX_SINK_NAME}"); then +# pactl load-module module-loopback source="${SINK_NAME}.monitor" sink="$DUPLEX_SINK_NAME" +#fi +#SINKMON_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${SINK_NAME}.monitor sink=${DUPLEX_SINK_NAME}/{x; s/\s*Module #\s*//g; p; q}") + +DEFAULT_SINK=$(pacmd dump | mawk '/set-default-sink/ {print $2}') +DEFAULT_SOURCE=$(pacmd dump | mawk '/set-default-source/ {print $2}') + +#if !(pactl list modules | grep -q "source=${DEFAULT_SINK} sink=${DUPLEX_SINK_NAME}"); then +#if !(pactl list modules | grep -q "source=${DUPLEX_SINK_NAME}.monitor sink=${DEFAULT_SINK}"); then +if !(pactl list modules | grep -q "source=${SINK_NAME}.monitor sink=${DEFAULT_SINK}"); then +# pactl load-module module-loopback source=${DEFAULT_SINK} sink="$DUPLEX_SINK_NAME" +# pactl load-module module-loopback source=${DUPLEX_SINK_NAME}.monitor sink="$DEFAULT_SINK" + pactl load-module module-loopback source=${SINK_NAME}.monitor sink="$DEFAULT_SINK" +fi +#DEFAULT_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${DEFAULT_SOURCE} sink=${DUPLEX_SINK_NAME}/{x; s/\s*Module #\s*//g; p; q}") +#DEFAULT_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${DUPLEX_SINK_NAME}.monitor sink=${DEFAULT_SINK}/{x; s/\s*Module #\s*//g; p; q}") +DEFAULT_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${SINK_NAME}.monitor sink=${DEFAULT_SINK}/{x; s/\s*Module #\s*//g; p; q}") + +pactl load-module module-echo-cancel \ + source_name="ipwebcam_efilter" source_master="${SINK_NAME}.monitor" source_properties="device.description='IP\ Webcam\ and\ Mic\ echo\ filter\ source'" \ + sink_name="default_efilter" sink_master="${DEFAULT_SINK}" sink_properties="device.description='IP\ Webcam\ and\ Mic\ echo\ filter\ sink'" \ + aec_method="webrtc" save_aec=1 use_volume_sharing=1 # Install and open pavucontrol as needed if ! can_run pavucontrol; then info "You don't have pavucontrol. I'll try to install its Debian/Ubuntu package." - sudo apt-get install pavucontrol + sudo apt-get install -y pavucontrol fi if ! pgrep pavucontrol; then - info "We will open now pavucontrol. You should leave it open to change the recording device of your video chat program to 'Monitor Null Output'. NOTE: make sure that in 'Output Devices' *all* devices are listed, and in the Playback tab the $GSTLAUNCH program sends its audio to the 'Null Sink'." + info "We will open now pavucontrol. You should leave it open to change the recording device of your video chat program to 'Monitor IP Webcam'. NOTE: make sure that in 'Output Devices' *all* devices are listed, and in the Playback tab the $GSTLAUNCH program sends its audio to the 'IP Webcam'." pavucontrol & fi # Check for gst-launch -GSTLAUNCH=gst-launch -if can_run apt-get; then +GSTLAUNCH=gst-launch-${GST_VER} +if [ $DIST = "Debian" ]; then # Debian - GSTLAUNCH=gst-launch if ! can_run "$GSTLAUNCH"; then info "You don't have gst-launch. I'll try to install its Debian/Ubuntu package." - sudo apt-get install gstreamer-tools + sudo apt-get install -y gstreamer${GST_VER}-tools fi elif can_run pacman; then # Arch - GSTLAUNCH=gst-launch-0.10 if ! can_run "$GSTLAUNCH"; then info "You don't have gst-launch. I'll try to install its Arch package." - sudo pacman -S gstreamer0.10 gstreamer0.10-good-plugins + sudo pacman -S gstreamer${GST_VER} gstreamer${GST_VER}-good-plugins fi fi if ! can_run "$GSTLAUNCH"; then @@ -282,18 +358,35 @@ fi # Start the GStreamer graph needed to grab the video and audio set +e -info "Using IP Webcam as webcam/microphone through v4l2loopback device $DEVICE and PulseAudio sink '$NULL_SINK'. You can now open your videochat app." +info "Using IP Webcam as webcam/microphone through v4l2loopback device $DEVICE. Microphone is directed to $SINK_NAME and multiplexed with ${DEFAULT_SOURCE}. You can now open your videochat app." + +WIDTH=640 +HEIGHT=480 +GST_FPS=5 +DIMENSIONS="width=$WIDTH,height=$HEIGHT" + +GST_0_10_CAPS="$GST_0_10_MIMETYPE,$GST_0_10_FORMAT,$DIMENSIONS" +CAPS="$GST_MIMETYPE,$GST_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" \ +#sudo v4l2loopback-ctl set-caps $GST_0_10_CAPS $DEVICE + "$GSTLAUNCH" -vt --gst-plugin-spew --gst-debug="$GST_DEBUG" \ - souphttpsrc location="http://$IP:$PORT/videofeed" do-timestamp=true is-live=true \ + souphttpsrc location="$VIDEO_URL" do-timestamp=true is-live=true \ ! multipartdemux \ ! jpegdec \ - ! ffmpegcolorspace ! "video/x-raw-yuv, format=(fourcc)YV12" \ - ! videoflip method="$FLIP_METHOD" ! videorate ! "video/x-raw-yuv, framerate=25/1" \ - ! v4l2sink device="$DEVICE" \ - souphttpsrc location="http://$IP:$PORT/audio.wav" do-timestamp=true is-live=true \ - ! wavparse ! audioconvert \ - ! volume volume=3 ! rglimiter \ - ! pulsesink device="$NULL_SINK" sync=false \ - 2>&1 | tee feed.log + $GST_FLIP \ + ! $GST_CONVERTER \ + ! videoscale \ + ! videorate \ + ! $CAPS \ + ! v4l2sink device="$DEVICE" sync=true \ + souphttpsrc location="$AUDIO_URL" do-timestamp=true is-live=true \ + ! wavparse \ + ! audioconvert \ + ! volume volume=3 \ + ! rglimiter \ + ! pulsesink device="$SINK_NAME" sync=true \ + 2>&1 | tee feed.log info "Disconnected from IP Webcam. Have a nice day!" + +pactl unload-module ${SINK_ID} -- cgit v1.2.3 From 190cc7606914e3b097b28702e3a5305199558436 Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Tue, 12 Jan 2016 08:43:11 -0800 Subject: some job control, prompting for user to end the stream, redirecting zenity noise to null --- prepare-videochat.sh | 110 ++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/prepare-videochat.sh b/prepare-videochat.sh index 38a36d2..31b1d1e 100755 --- a/prepare-videochat.sh +++ b/prepare-videochat.sh @@ -118,28 +118,35 @@ WIFI_IP=192.168.2.140 # Port on which IP Webcam is listening PORT=8080 +# Dimensions of video +WIDTH=640 +HEIGHT=480 + +# Frame rate of video +GST_FPS=5 + ### FUNCTIONS has_kernel_module() { - sudo modprobe -q "$1" + sudo modprobe -q "$1" > /dev/null 2>&1 } error() { - zenity --error --text "$@" + zenity --error --text "$@" > /dev/null 2>&1 exit 1 } warning() { - zenity --warning --text "$@" + zenity --warning --text "$@" > /dev/null 2>&1 } info() { - zenity --info --text "$@" + zenity --info --text "$@" > /dev/null 2>&1 } confirm() { - zenity --question --text "$@" + zenity --question --text "$@" > /dev/null 2>&1 } can_run() { @@ -177,6 +184,15 @@ start_iw_server() { sleep 2s } +modid_by_sinkname() { + pacmd list-sinks | grep -e 'name:' -e 'module:' | grep -A1 "name: <$1>" | grep module: | cut -f2 -d: | tr -d ' ' +} + +modid_by_sourcename() { + pacmd list-sources | grep -e 'name:' -e 'module:' | grep -A1 "name: <$1>" | grep module: | cut -f2 -d: | tr -d ' ' +} + + if can_run lsb_release; then DIST=`lsb_release -i | awk -F: '{print $2}'` RELEASE=`lsb_release -r | awk -F: '{print $2}'` @@ -288,54 +304,31 @@ while ! iw_server_is_started; do info "The IP Webcam video feed is not reachable at $VIDEO_URL. Please open IP Webcam in your phone and start the server." done -SINK_NAME="ipwebcam" -# Load null-sink if needed -if !(pactl list sinks | grep -q $SINK_NAME); then - pactl load-module module-null-sink sink_name="$SINK_NAME" sink_properties="device.description='IP\ Webcam'" -fi -SINK_ID=$(pactl list sinks | sed -n -e "/Owner Module:/h; /$SINK_NAME.monitor/{x; s/\s*Owner Module:\s*//g; p; q}") - -#DUPLEX_SINK_NAME="ipwebcam_mic" -#if !(pactl list sinks | grep -q $DUPLEX_SINK_NAME); then -# pactl load-module module-null-sink sink_name="$DUPLEX_SINK_NAME" sink_properties="device.description='IP\ Webcam\ and\ Mic\ MUX',filter.want=echo-cancel" -#fi -#DUPLEX_SINK_ID=$(pactl list sinks | sed -n -e "/Owner Module:/h; /$DUPLEX_SINK_NAME.monitor/{x; s/\s*Owner Module:\s*//g; p; q}") - - -#if !(pactl list modules | grep -q "source=${SINK_NAME}.monitor sink=${DUPLEX_SINK_NAME}"); then -# pactl load-module module-loopback source="${SINK_NAME}.monitor" sink="$DUPLEX_SINK_NAME" -#fi -#SINKMON_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${SINK_NAME}.monitor sink=${DUPLEX_SINK_NAME}/{x; s/\s*Module #\s*//g; p; q}") - DEFAULT_SINK=$(pacmd dump | mawk '/set-default-sink/ {print $2}') DEFAULT_SOURCE=$(pacmd dump | mawk '/set-default-source/ {print $2}') -#if !(pactl list modules | grep -q "source=${DEFAULT_SINK} sink=${DUPLEX_SINK_NAME}"); then -#if !(pactl list modules | grep -q "source=${DUPLEX_SINK_NAME}.monitor sink=${DEFAULT_SINK}"); then -if !(pactl list modules | grep -q "source=${SINK_NAME}.monitor sink=${DEFAULT_SINK}"); then -# pactl load-module module-loopback source=${DEFAULT_SINK} sink="$DUPLEX_SINK_NAME" -# pactl load-module module-loopback source=${DUPLEX_SINK_NAME}.monitor sink="$DEFAULT_SINK" - pactl load-module module-loopback source=${SINK_NAME}.monitor sink="$DEFAULT_SINK" -fi -#DEFAULT_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${DEFAULT_SOURCE} sink=${DUPLEX_SINK_NAME}/{x; s/\s*Module #\s*//g; p; q}") -#DEFAULT_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${DUPLEX_SINK_NAME}.monitor sink=${DEFAULT_SINK}/{x; s/\s*Module #\s*//g; p; q}") -DEFAULT_LOOP_ID=$(pactl list modules | sed -n -e "/Module #/h; /source=${SINK_NAME}.monitor sink=${DEFAULT_SINK}/{x; s/\s*Module #\s*//g; p; q}") - -pactl load-module module-echo-cancel \ - source_name="ipwebcam_efilter" source_master="${SINK_NAME}.monitor" source_properties="device.description='IP\ Webcam\ and\ Mic\ echo\ filter\ source'" \ - sink_name="default_efilter" sink_master="${DEFAULT_SINK}" sink_properties="device.description='IP\ Webcam\ and\ Mic\ echo\ filter\ sink'" \ - aec_method="webrtc" save_aec=1 use_volume_sharing=1 - -# Install and open pavucontrol as needed -if ! can_run pavucontrol; then - info "You don't have pavucontrol. I'll try to install its Debian/Ubuntu package." - sudo apt-get install -y pavucontrol +SINK_NAME="ipwebcam" +SINK_ID=$(modid_by_sinkname $SINK_NAME) +ECANCEL_ID=$(modid_by_sinkname "${SINK_NAME}_echo_cancel") + +if [ -z $SINK_ID ] ; then + SINK_ID=$(pactl load-module module-null-sink \ + rate=44100 \ + format=s16le \ + sink_name="$SINK_NAME" \ + sink_properties="device.description='IP\ Webcam'") fi -if ! pgrep pavucontrol; then - info "We will open now pavucontrol. You should leave it open to change the recording device of your video chat program to 'Monitor IP Webcam'. NOTE: make sure that in 'Output Devices' *all* devices are listed, and in the Playback tab the $GSTLAUNCH program sends its audio to the 'IP Webcam'." - pavucontrol & + +if [ -z $ECANCEL_ID ] ; then + ECANCEL_ID=$(pactl load-module module-echo-cancel \ + sink_name="${SINK_NAME}_echo_cancel" \ + source_master="$SINK_NAME.monitor" \ + sink_master="$DEFAULT_SINK" \ + aec_method="webrtc" save_aec=1 use_volume_sharing=1) fi +pactl set-default-source $SINK_NAME.monitor + # Check for gst-launch GSTLAUNCH=gst-launch-${GST_VER} if [ $DIST = "Debian" ]; then @@ -358,18 +351,14 @@ fi # Start the GStreamer graph needed to grab the video and audio set +e -info "Using IP Webcam as webcam/microphone through v4l2loopback device $DEVICE. Microphone is directed to $SINK_NAME and multiplexed with ${DEFAULT_SOURCE}. You can now open your videochat app." -WIDTH=640 -HEIGHT=480 -GST_FPS=5 DIMENSIONS="width=$WIDTH,height=$HEIGHT" GST_0_10_CAPS="$GST_0_10_MIMETYPE,$GST_0_10_FORMAT,$DIMENSIONS" CAPS="$GST_MIMETYPE,$GST_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" \ #sudo v4l2loopback-ctl set-caps $GST_0_10_CAPS $DEVICE -"$GSTLAUNCH" -vt --gst-plugin-spew --gst-debug="$GST_DEBUG" \ +"$GSTLAUNCH" -e -vt --gst-plugin-spew --gst-debug="$GST_DEBUG" \ souphttpsrc location="$VIDEO_URL" do-timestamp=true is-live=true \ ! multipartdemux \ ! jpegdec \ @@ -385,8 +374,21 @@ CAPS="$GST_MIMETYPE,$GST_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" \ ! volume volume=3 \ ! rglimiter \ ! pulsesink device="$SINK_NAME" sync=true \ - 2>&1 | tee feed.log + 2>&1 > feed.log & -info "Disconnected from IP Webcam. Have a nice day!" +GSTLAUNCH_PID=$! + +echo "PID of $GSTLAUNCH is $GSTLAUNCH_PID" + +info "IP Webcam video is streaming through v4l2loopback device $DEVICE. +IP Webcam audio is streaming through pulseaudio sink '$SINK_NAME'. +You can now open your videochat app." +read -p "Press enter to end stream" + +kill $GSTLAUNCH_PID +pactl set-default-source $DEFAULT_SOURCE +pactl unload-module ${ECANCEL_ID} pactl unload-module ${SINK_ID} + +info "Disconnected from IP Webcam. Have a nice day!" -- cgit v1.2.3 From bc531a792ae35e770ef94d9502a3c10902a422f3 Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Tue, 12 Jan 2016 09:45:51 -0800 Subject: renamed CAPS to VIDEO_CAPS to prepare for supplying audio caps to the gst-launcher pipeline --- prepare-videochat.sh | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/prepare-videochat.sh b/prepare-videochat.sh index 31b1d1e..37a01a0 100755 --- a/prepare-videochat.sh +++ b/prepare-videochat.sh @@ -202,22 +202,35 @@ elif [ -f /etc/debian_version ] ; then fi GST_VER="0.10" -GST_CONVERTER="ffmpegcolorspace" -GST_MIMETYPE="video/x-raw-yuv" -GST_FORMAT="format=(fourcc)YV12" +GST_VIDEO_CONVERTER="ffmpegcolorspace" +GST_VIDEO_MIMETYPE="video/x-raw-yuv" +GST_VIDEO_FORMAT="format=(fourcc)YV12" -GST_0_10_MIMETYPE=$GST_MIMETYPE -GST_0_10_FORMAT=$GST_FORMAT +GST_AUDIO_MIMETYPE="audio/x-raw-int" +GST_AUDIO_FORMAT="width=16,depth=16,endianness=1234,signed=true,channels=1" +GST_AUDIO_RATE="rate=41000" + +GST_0_10_VIDEO_MIMETYPE=$GST_VIDEO_MIMETYPE +GST_0_10_VIDEO_FORMAT=$GST_VIDEO_FORMAT if [ $DIST = "Debian" -a `echo "$RELEASE >= 8.0" | bc` -eq 1 ] ||\ [ $DIST = "Ubuntu" -a `echo "$RELEASE >= 14.04" | bc` -eq 1 ] then GST_VER="1.0" - GST_CONVERTER="videoconvert" - GST_MIMETYPE="video/x-raw" - GST_FORMAT="format=YV12" + GST_VIDEO_CONVERTER="videoconvert" + GST_VIDEO_MIMETYPE="video/x-raw" + GST_VIDEO_FORMAT="format=YV12" + + GST_AUDIO_MIMETYPE="audio/x-raw" + GST_AUDIO_FORMAT="format=F32E,channels=1" fi +DIMENSIONS="width=$WIDTH,height=$HEIGHT" + +GST_0_10_VIDEO_CAPS="$GST_0_10_VIDEO_MIMETYPE,$GST_0_10_VIDEO_FORMAT,$DIMENSIONS" +VIDEO_CAPS="$GST_VIDEO_MIMETYPE,$GST_VIDEO_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" +AUDIO_CAPS="$GST_AUDIO_MIMETYPE,$GST_AUDIO_FORMAT,$GST_AUDIO_RATE" + # GStreamer debug string (see gst-launch manpage) GST_DEBUG=souphttpsrc:0,videoflip:0,$GST_CONVERTER:0,v4l2sink:0,pulse:0 @@ -313,8 +326,6 @@ ECANCEL_ID=$(modid_by_sinkname "${SINK_NAME}_echo_cancel") if [ -z $SINK_ID ] ; then SINK_ID=$(pactl load-module module-null-sink \ - rate=44100 \ - format=s16le \ sink_name="$SINK_NAME" \ sink_properties="device.description='IP\ Webcam'") fi @@ -352,21 +363,18 @@ fi # Start the GStreamer graph needed to grab the video and audio set +e -DIMENSIONS="width=$WIDTH,height=$HEIGHT" - -GST_0_10_CAPS="$GST_0_10_MIMETYPE,$GST_0_10_FORMAT,$DIMENSIONS" -CAPS="$GST_MIMETYPE,$GST_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" \ -#sudo v4l2loopback-ctl set-caps $GST_0_10_CAPS $DEVICE +#sudo v4l2loopback-ctl set-caps $GST_0_10_VIDEO_CAPS $DEVICE -"$GSTLAUNCH" -e -vt --gst-plugin-spew --gst-debug="$GST_DEBUG" \ +"$GSTLAUNCH" -e -vt --gst-plugin-spew \ + --gst-debug="$GST_DEBUG" \ souphttpsrc location="$VIDEO_URL" do-timestamp=true is-live=true \ ! multipartdemux \ ! jpegdec \ $GST_FLIP \ - ! $GST_CONVERTER \ + ! $GST_VIDEO_CONVERTER \ ! videoscale \ ! videorate \ - ! $CAPS \ + ! $VIDEO_CAPS \ ! v4l2sink device="$DEVICE" sync=true \ souphttpsrc location="$AUDIO_URL" do-timestamp=true is-live=true \ ! wavparse \ @@ -378,8 +386,6 @@ CAPS="$GST_MIMETYPE,$GST_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" \ GSTLAUNCH_PID=$! -echo "PID of $GSTLAUNCH is $GSTLAUNCH_PID" - info "IP Webcam video is streaming through v4l2loopback device $DEVICE. IP Webcam audio is streaming through pulseaudio sink '$SINK_NAME'. You can now open your videochat app." @@ -387,7 +393,7 @@ You can now open your videochat app." read -p "Press enter to end stream" kill $GSTLAUNCH_PID -pactl set-default-source $DEFAULT_SOURCE +pactl set-default-source ${DEFAULT_SOURCE} pactl unload-module ${ECANCEL_ID} pactl unload-module ${SINK_ID} -- cgit v1.2.3 From 325852de5b8af4264e9c955592bc8b1c98e39961 Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Tue, 12 Jan 2016 10:28:13 -0800 Subject: added an audioresample plugin to the audio pipeline --- prepare-videochat.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/prepare-videochat.sh b/prepare-videochat.sh index 37a01a0..515476f 100755 --- a/prepare-videochat.sh +++ b/prepare-videochat.sh @@ -379,6 +379,7 @@ set +e souphttpsrc location="$AUDIO_URL" do-timestamp=true is-live=true \ ! wavparse \ ! audioconvert \ + ! audioresample \ ! volume volume=3 \ ! rglimiter \ ! pulsesink device="$SINK_NAME" sync=true \ -- cgit v1.2.3 From 23771742ee68716b64add081114e43f4f917fb38 Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Tue, 12 Jan 2016 19:22:27 -0800 Subject: it is working quite well now. --- prepare-videochat.sh | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/prepare-videochat.sh b/prepare-videochat.sh index 515476f..5b7a43d 100755 --- a/prepare-videochat.sh +++ b/prepare-videochat.sh @@ -1,7 +1,10 @@ #!/bin/bash -# Script for using IP Webcam as a microphone/webcam in Ubuntu 13.04 and Arch +# Script for using IP Webcam as a microphone/webcam in Debian Jessie, +# Ubuntu 13.04, 14.04 and Arch + # Copyright (C) 2011-2013 Antonio García Domínguez +# Copyright (C) 2016 C.J. Adams-Collier # Licensed under GPLv3 # Usage: ./prepare-videochat.sh [flip method] @@ -31,8 +34,7 @@ # 1. Does v4l2loopback work properly? # # Try running these commands. You'll first need to install mplayer and -# ensure that your user can write to /dev/video*), and then run these -# commands on one tab: +# ensure that your user can write to /dev/video*). # # sudo modprobe -r v4l2loopback # ls /dev/video* @@ -40,11 +42,9 @@ # sudo modprobe v4l2loopback # ls /dev/video* # (Note down the new devices: let X be the number of the first new device.) -# gst-launch videotestsrc ! v4l2sink device=/dev/videoX -# -# Now go to another tab and use mplayer to play it back: +# v4l2-ctl -D -d /dev/videoX +# gst-launch videotestsrc ! v4l2sink device=/dev/videoX & mplayer -tv device=/dev/videoX tv:// # -# mplayer -tv device=/dev/videoX tv:// # # You should be able to see the GStreamer test video source, which is # like a TV test card. Otherwise, there's an issue in your v4l2loopback @@ -327,6 +327,8 @@ ECANCEL_ID=$(modid_by_sinkname "${SINK_NAME}_echo_cancel") if [ -z $SINK_ID ] ; then SINK_ID=$(pactl load-module module-null-sink \ sink_name="$SINK_NAME" \ + format=s16le \ + rate=44100 \ sink_properties="device.description='IP\ Webcam'") fi @@ -335,7 +337,7 @@ if [ -z $ECANCEL_ID ] ; then sink_name="${SINK_NAME}_echo_cancel" \ source_master="$SINK_NAME.monitor" \ sink_master="$DEFAULT_SINK" \ - aec_method="webrtc" save_aec=1 use_volume_sharing=1) + aec_method="webrtc" save_aec=true use_volume_sharing=true) fi pactl set-default-source $SINK_NAME.monitor @@ -377,11 +379,7 @@ set +e ! $VIDEO_CAPS \ ! v4l2sink device="$DEVICE" sync=true \ souphttpsrc location="$AUDIO_URL" do-timestamp=true is-live=true \ - ! wavparse \ - ! audioconvert \ - ! audioresample \ - ! volume volume=3 \ - ! rglimiter \ + ! audio/x-raw,format=S16LE,layout=interleaved,rate=44100,channels=1 \ ! pulsesink device="$SINK_NAME" sync=true \ 2>&1 > feed.log & -- cgit v1.2.3 From e1d45cc485265e0fde2d8e189d638e86eeb531fe Mon Sep 17 00:00:00 2001 From: "C.J. Adams-Collier" Date: Tue, 12 Jan 2016 19:49:27 -0800 Subject: the audio caps are now in a variable called $GST_AUDIO_CAPS and I re-named $VIDEO_CAPS to $GST_VIDEO_CAPS. I have also created $PA_AUDIO_CAPS which basically mirrors the $GST_AUDIO_CAPS variable, but is formatted for application to the module-null-sink --- prepare-videochat.sh | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/prepare-videochat.sh b/prepare-videochat.sh index 5b7a43d..55be954 100755 --- a/prepare-videochat.sh +++ b/prepare-videochat.sh @@ -102,7 +102,7 @@ fi # If your "adb" is not in your $PATH, set the full path to it here. # If "adb" is in your $PATH, you don't have to change this option. ADB_PATH=~/bin/android-sdk-linux_x86/platform-tools/adb -if which adb; then +if which adb > /dev/null ; then ADB=$(which adb) else ADB=$ADB_PATH @@ -207,9 +207,12 @@ GST_VIDEO_MIMETYPE="video/x-raw-yuv" GST_VIDEO_FORMAT="format=(fourcc)YV12" GST_AUDIO_MIMETYPE="audio/x-raw-int" -GST_AUDIO_FORMAT="width=16,depth=16,endianness=1234,signed=true,channels=1" -GST_AUDIO_RATE="rate=41000" +GST_AUDIO_FORMAT="width=16,depth=16,endianness=1234,signed=true" +GST_AUDIO_RATE="rate=44100" +GST_AUDIO_CHANNELS="channels=1" +GST_AUDIO_LAYOUT="" +GST_1_0_AUDIO_FORMAT="format=S16LE" GST_0_10_VIDEO_MIMETYPE=$GST_VIDEO_MIMETYPE GST_0_10_VIDEO_FORMAT=$GST_VIDEO_FORMAT @@ -222,14 +225,16 @@ then GST_VIDEO_FORMAT="format=YV12" GST_AUDIO_MIMETYPE="audio/x-raw" - GST_AUDIO_FORMAT="format=F32E,channels=1" + GST_AUDIO_FORMAT=$GST_1_0_AUDIO_FORMAT + GST_AUDIO_LAYOUT=",layout=interleaved" fi DIMENSIONS="width=$WIDTH,height=$HEIGHT" GST_0_10_VIDEO_CAPS="$GST_0_10_VIDEO_MIMETYPE,$GST_0_10_VIDEO_FORMAT,$DIMENSIONS" -VIDEO_CAPS="$GST_VIDEO_MIMETYPE,$GST_VIDEO_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" -AUDIO_CAPS="$GST_AUDIO_MIMETYPE,$GST_AUDIO_FORMAT,$GST_AUDIO_RATE" +GST_VIDEO_CAPS="$GST_VIDEO_MIMETYPE,$GST_VIDEO_FORMAT,$DIMENSIONS,framerate=$GST_FPS/1" +GST_AUDIO_CAPS="$GST_AUDIO_MIMETYPE,$GST_AUDIO_FORMAT$GST_AUDIO_LAYOUT,$GST_AUDIO_RATE,$GST_AUDIO_CHANNELS" +PA_AUDIO_CAPS="$GST_AUDIO_FORMAT $GST_AUDIO_RATE $GST_AUDIO_CHANNELS" # GStreamer debug string (see gst-launch manpage) GST_DEBUG=souphttpsrc:0,videoflip:0,$GST_CONVERTER:0,v4l2sink:0,pulse:0 @@ -327,8 +332,7 @@ ECANCEL_ID=$(modid_by_sinkname "${SINK_NAME}_echo_cancel") if [ -z $SINK_ID ] ; then SINK_ID=$(pactl load-module module-null-sink \ sink_name="$SINK_NAME" \ - format=s16le \ - rate=44100 \ + $PA_AUDIO_CAPS \ sink_properties="device.description='IP\ Webcam'") fi @@ -337,6 +341,7 @@ if [ -z $ECANCEL_ID ] ; then sink_name="${SINK_NAME}_echo_cancel" \ source_master="$SINK_NAME.monitor" \ sink_master="$DEFAULT_SINK" \ + $PA_AUDIO_CAPS \ aec_method="webrtc" save_aec=true use_volume_sharing=true) fi @@ -376,10 +381,10 @@ set +e ! $GST_VIDEO_CONVERTER \ ! videoscale \ ! videorate \ - ! $VIDEO_CAPS \ + ! $GST_VIDEO_CAPS \ ! v4l2sink device="$DEVICE" sync=true \ souphttpsrc location="$AUDIO_URL" do-timestamp=true is-live=true \ - ! audio/x-raw,format=S16LE,layout=interleaved,rate=44100,channels=1 \ + ! $GST_AUDIO_CAPS \ ! pulsesink device="$SINK_NAME" sync=true \ 2>&1 > feed.log & @@ -389,9 +394,10 @@ info "IP Webcam video is streaming through v4l2loopback device $DEVICE. IP Webcam audio is streaming through pulseaudio sink '$SINK_NAME'. You can now open your videochat app." -read -p "Press enter to end stream" +echo "Press enter to end stream" +perl -e '' -kill $GSTLAUNCH_PID +kill $GSTLAUNCH_PID > /dev/null 2>&1 || echo "" pactl set-default-source ${DEFAULT_SOURCE} pactl unload-module ${ECANCEL_ID} pactl unload-module ${SINK_ID} -- cgit v1.2.3