Skip to content

Instantly share code, notes, and snippets.

@philhartung
philhartung / ebur.sh
Last active May 17, 2022
EBUR128 loudness meter using ffplay, 800x480 resolution for Raspberry Pi touchscreen
View ebur.sh
#/bin/sh
ffplay -exitonkeydown -exitonmousedown -fs -fflags nobuffer -probesize 32 -analyzeduration 1 -f lavfi -i "amovie=default:f=alsa,asplit=2[sv][eb];\
[sv]showvolume=b=0:o=v:w=480:h=23[sv-v];\
[eb]ebur128=video=1:size=754x480[eb-v][out1];\
[eb-v][sv-v]hstack=2[out0]"
@philhartung
philhartung / aes67.py
Created Dec 8, 2021
Simple AES67 implementation using gstreamer. Does not implement any discovery.
View aes67.py
import sys
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstNet', '1.0')
from gi.repository import Gst, GstNet, GObject, GLib
Gst.init([])
mainloop = GLib.MainLoop()
@philhartung
philhartung / sine.js
Last active Jun 9, 2021
Generate sine wave audio and output it to default audiodevice
View sine.js
const { RtAudio, RtAudioFormat } = require('audify');
const rtAudio = new RtAudio();
// constants
const samplerate = 48000;
const ffp = 48;
// audio device
let audioOutput = {
deviceId: rtAudio.getDefaultOutputDevice(),
@philhartung
philhartung / ptpanalyzer.js
Last active Feb 13, 2022
First draft of AES67 RTP timestamp analyzer tool. Prints RTP to PTP timestamp difference min/avg/max in console
View ptpanalyzer.js
const dgram = require('dgram');
const chalk = require('chalk');
const ptpv2 = require('ptpv2');
let interface = '10.0.0.12';
//let multicastAddr = '239.69.161.58';
let multicastAddr = '239.69.80.114';
let samplerate = 48000;
let client = dgram.createSocket({ type: 'udp4', reuseAddr: true });
@philhartung
philhartung / stream.sh
Last active Jun 5, 2022
Stream a video via network to OBS with low latency (<100ms)
View stream.sh
#!/bin/sh
# host is the IP of the receiving computer
host="192.168.0.101"
gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-h264, width=1920, height=1080, framerate=30/1 ! rtph264pay ! udpsink host=$host port=5004
View monitor.sh
#!/bin/sh
ffplay -fs -f v4l2 -i /dev/video2 -input_format mjpeg -video_size 1920x1080 -framerate 60.0 -vf "format=yuv444p,split=4[a][b][c][d];\
[a]histogram=c=1,scale=w=-1:h=1080,pad=1920:ih:(ow-iw)/2[aa];\
[b]scale=1920x1080[bb];\
[c]waveform=scale=ire,scale=1920x1080,\
drawbox=0:85:1920:3:GreenYellow:fill,\
drawtext=text=100:x=0:y=50:fontsize=35:fontcolor=GreenYellow,\
drawbox=0:317:1920:3:GreenYellow:fill,\
drawtext=text=75:x=0:y=282:fontsize=35:fontcolor=GreenYellow,\
drawbox=0:546:1920:3:GreenYellow:fill,\
@philhartung
philhartung / aes67_play.sh
Last active Dec 5, 2021
Play a AES67 stream
View aes67_play.sh
#!/bin/sh
gst-launch-1.0 udpsrc address=239.69.161.58 port=5004 multicast-iface=eth0 !\
application/x-rtp, clock-rate=48000, channels=2 !\
rtpjitterbuffer !\
rtpL24depay !\
audioconvert !\
audioresample !\
autoaudiosink
@philhartung
philhartung / aes67_icecast.sh
Last active Nov 6, 2020
AES67 <> Icecast relay with gstreamer
View aes67_icecast.sh
#!/bin/sh
gst-launch-1.0 udpsrc address=239.69.161.58 port=5004 multicast-iface=eth0 !\
application/x-rtp, clock-rate=48000, channels=2 !\
rtpjitterbuffer !\
rtpL24depay !\
audioconvert !\
lamemp3enc !\
shout2send mount=/test.mp3 port=8000 username=source password=XXX ip=10.10.0.100
@philhartung
philhartung / dante-aes67-relay.js
Last active Jun 21, 2022
Relay a Dante multicast stream to AES67. This assumes the AES67 device is synced to the same PTP master, as no PTP timestamping is done (timestamp from Dante is copied to AES67 RTP packet)
View dante-aes67-relay.js
const dgram = require('dgram');
const client = dgram.createSocket({ type: 'udp4', reuseAddr: true });
const sdp = require('./sdp');
//config
const addr = '10.10.1.100';
const danteMulticast = '239.255.220.221';
const aes67Multicast = '239.69.1.122';
const samplerate = 48000;
const channels = 2;
@philhartung
philhartung / rtp-to-speaker.js
Last active Jun 11, 2020
Play raw audio from RTP stream
View rtp-to-speaker.js
const Speaker = require('speaker');
const dgram = require('dgram');
const client = dgram.createSocket('udp4');
var speaker = new Speaker({
channels: 2,
bitDepth: 16,
sampleRate: 48000
})