mirror of
https://github.com/matthew1000/gstreamer-cheat-sheet.git
synced 2025-02-17 15:15:17 +00:00
Mixing examples
This commit is contained in:
parent
8ac967d082
commit
40ba05cd8e
3 changed files with 134 additions and 4 deletions
20
mixing.md
20
mixing.md
|
@ -1,4 +1,8 @@
|
||||||
# Mixing video (GStreamer command-line cheat sheet)
|
# Mixing (GStreamer command-line cheat sheet)
|
||||||
|
|
||||||
|
This page talks about mixing video (i.e. replacing or overlaying), and also mixing audio (i.e. replacing or merging audio tracks). We'll do one at a time.
|
||||||
|
|
||||||
|
## Mixing video
|
||||||
|
|
||||||
The element `compositor` allows video to be mixed (overlayed, put side-by-side, etc).
|
The element `compositor` allows video to be mixed (overlayed, put side-by-side, etc).
|
||||||
|
|
||||||
|
@ -70,7 +74,7 @@ gst-launch-1.0 \
|
||||||
mix.
|
mix.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compositor with just one sources
|
### Compositor with just one source
|
||||||
|
|
||||||
It is possible for a compositor to have just one source. This example has the test source of a bouncing ball. It also has the audio test source included (muxed).
|
It is possible for a compositor to have just one source. This example has the test source of a bouncing ball. It also has the audio test source included (muxed).
|
||||||
|
|
||||||
|
@ -84,3 +88,15 @@ gst-launch-1.0 \
|
||||||
mpegtsmux name=muxer ! queue ! \
|
mpegtsmux name=muxer ! queue ! \
|
||||||
tcpserversink host=127.0.0.1 port=7001 recover-policy=keyframe sync-method=latest-keyframe sync=false
|
tcpserversink host=127.0.0.1 port=7001 recover-policy=keyframe sync-method=latest-keyframe sync=false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Mixing audio
|
||||||
|
|
||||||
|
Use the `audiomixer` element to mix audio. It replaces the `adder` element, which struggles under some circumstances (according to the [GStreamer 1.14 release notes](https://gstreamer.freedesktop.org/releases/1.14/)).
|
||||||
|
|
||||||
|
Mix to audio streams:
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-launch-1.0 audiotestsrc freq=100 ! audiomixer name=mix ! audioconvert ! alsasink audiotestsrc freq=500 ! mix.
|
||||||
|
```
|
||||||
|
|
||||||
|
[This Python example(python_examples/audio_dynamic_add.py)] shows a dynamic equivalent of this example - the second test source is only mixed when the user presses Enter.
|
||||||
|
|
79
python_examples/audio-dynamic-add.py
Normal file
79
python_examples/audio-dynamic-add.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Shows how two test sources can be mixed together.
|
||||||
|
#
|
||||||
|
# A variation of what's on
|
||||||
|
# https://stackoverflow.com/questions/3899666/adding-and-removing-audio-sources-to-from-gstreamer-pipeline-on-the-go
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gst', '1.0')
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import Gst, GObject, Gtk
|
||||||
|
|
||||||
|
Gst.init(None)
|
||||||
|
GObject.threads_init()
|
||||||
|
|
||||||
|
# def buzzersrc1_probe_callback(a,b):
|
||||||
|
# print("buzzersrc1_probe_callback called")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# First create our pipeline
|
||||||
|
pipe = Gst.Pipeline.new("mypipe")
|
||||||
|
|
||||||
|
audiomixer = Gst.ElementFactory.make("audiomixer","audiomixer")
|
||||||
|
pipe.add(audiomixer)
|
||||||
|
|
||||||
|
# Gather a request sink pad on the mixer
|
||||||
|
sinkpad1=audiomixer.get_request_pad("sink_%u")
|
||||||
|
print("sinkpad1:" + str(sinkpad1))
|
||||||
|
|
||||||
|
# Create the first buzzer..
|
||||||
|
buzzer1 = Gst.ElementFactory.make("audiotestsrc","buzzer1")
|
||||||
|
buzzer1.set_property("freq",1000)
|
||||||
|
pipe.add(buzzer1)
|
||||||
|
# .. and connect it's source pad to the previously gathered request pad
|
||||||
|
buzzersrc1=buzzer1.get_static_pad("src")
|
||||||
|
buzzersrc1.link(sinkpad1)
|
||||||
|
|
||||||
|
# Add some output
|
||||||
|
output = Gst.ElementFactory.make("autoaudiosink", "audio_out")
|
||||||
|
pipe.add(output)
|
||||||
|
audiomixer.link(output)
|
||||||
|
|
||||||
|
# Start the playback
|
||||||
|
pipe.set_state(Gst.State.PLAYING)
|
||||||
|
|
||||||
|
input("1kHz test sound. Press <ENTER> to continue.")
|
||||||
|
|
||||||
|
# Get an another request sink pad on the mixer
|
||||||
|
sinkpad2=audiomixer.get_request_pad("sink_%u")
|
||||||
|
|
||||||
|
# Create an another buzzer and connect it the same way
|
||||||
|
buzzer2 = Gst.ElementFactory.make("audiotestsrc","buzzer2")
|
||||||
|
buzzer2.set_property("freq",500)
|
||||||
|
pipe.add(buzzer2)
|
||||||
|
|
||||||
|
buzzersrc2=buzzer2.get_static_pad("src")
|
||||||
|
buzzersrc2.link(sinkpad2)
|
||||||
|
|
||||||
|
# Start the second buzzer (other ways streaming stops because of starvation)
|
||||||
|
buzzer2.set_state(Gst.State.PLAYING)
|
||||||
|
|
||||||
|
input("1kHz + 500Hz test sound playing simoultenously. Press <ENTER> to continue.")
|
||||||
|
|
||||||
|
# Before removing a source, we must use pad blocking to prevent state changes
|
||||||
|
# buzzersrc1.set_blocked(True)
|
||||||
|
# I think this gets replaced with:
|
||||||
|
# buzzersrc1.add_probe(Gst.PadProbeType.BLOCK_DOWNSTREAM, buzzersrc1_probe_callback)
|
||||||
|
# but it doesn't seem to be required.
|
||||||
|
|
||||||
|
# Stop the first buzzer
|
||||||
|
buzzer1.set_state(Gst.State.NULL)
|
||||||
|
# Unlink from the mixer
|
||||||
|
buzzersrc1.unlink(sinkpad2)
|
||||||
|
# Release the mixers first sink pad
|
||||||
|
audiomixer.release_request_pad(sinkpad1)
|
||||||
|
# Because here none of the audiomixer's sink pads block, streaming continues
|
||||||
|
|
||||||
|
input("Only 500Hz test sound. Press <ENTER> to stop.")
|
|
@ -1,5 +1,7 @@
|
||||||
# Test streams (GStreamer command-line cheat sheet)
|
# Test streams (GStreamer command-line cheat sheet)
|
||||||
|
|
||||||
|
## Video test streams
|
||||||
|
|
||||||
### Display a test pattern
|
### Display a test pattern
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -31,13 +33,46 @@ To change the width and/or height, pass width and height immediately afterwards,
|
||||||
gst-launch-1.0 -v videotestsrc pattern=snow ! video/x-raw,width=1280,height=720 ! autovideosink
|
gst-launch-1.0 -v videotestsrc pattern=snow ! video/x-raw,width=1280,height=720 ! autovideosink
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Audio test streams
|
||||||
|
|
||||||
### Listen to a test audio (beep)
|
### Listen to a test audio (beep)
|
||||||
|
|
||||||
```
|
```
|
||||||
gst-launch-1.0 audiotestsrc ! audioconvert ! autoaudiosink
|
gst-launch-1.0 audiotestsrc ! autoaudiosink
|
||||||
```
|
```
|
||||||
|
|
||||||
### View test pattern and hear test audio
|
You can change the pitch using the `freq` property:
|
||||||
|
|
||||||
|
```
|
||||||
|
# This creates a higher beep:
|
||||||
|
gst-launch-1.0 audiotestsrc freq=1000 ! autoaudiosink
|
||||||
|
```
|
||||||
|
|
||||||
|
The [mixing page](./mixing.md) shows how two different frequency audio test streams can be mixed together.
|
||||||
|
|
||||||
|
You can change the *volume* by setting the `volume` property between `0` and `1`. E.g. for a quiet beep:
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-launch-1.0 audiotestsrc volume=0.1 ! autoaudiosink
|
||||||
|
```
|
||||||
|
|
||||||
|
### White noise
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-launch-1.0 audiotestsrc wave="white-noise" ! autoaudiosink
|
||||||
|
```
|
||||||
|
|
||||||
|
There are variations (e.g. _red noise_) - see the [docs](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-audiotestsrc.html) for a complete list.
|
||||||
|
|
||||||
|
### Silence
|
||||||
|
|
||||||
|
If you need an audio stream with nothing in:
|
||||||
|
|
||||||
|
```
|
||||||
|
gst-launch-1.0 audiotestsrc wave="silence" ! autoaudiosink
|
||||||
|
```
|
||||||
|
|
||||||
|
## Combining audio and video test streams
|
||||||
|
|
||||||
Combine both the test pattern and test audio:
|
Combine both the test pattern and test audio:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue