fzwoch / obs-gstreamer

GStreamer OBS Studio plugin
GNU General Public License v2.0
346 stars 35 forks source link

Add "audio-only" input option #9

Closed crossan007 closed 5 years ago

crossan007 commented 6 years ago

Currently, the plugin supports audio as part of the source, but an audio-only plugin would be nice so that when the scene no longer includes the source, the pipeline may still render audio into the mixer.

Specifically, this pipeline comes to mind:

videotestsrc pattern=18 ! video. alsasrc name=audiosrc device=hw:1 ! audio/x-raw,channels=32,layout=interleaved,rate=48000 ! queue ! deinterleave name=d interleave name=i d.src_0 ! queue ! audioconvert  ! i.sink_0  d.src_1 ! queue ! audioconvert  ! i.sink_1 i. ! audio.

I'd like to not need to map anything to the .video sink, and allow this pipeline to run regardless of the currently live scene (and whether the obs-gstreamer source is present on that scene)

fzwoch commented 6 years ago

Isn't that already working? Having an audio only pipeline? At least that was my intention. Remove any video paths and the sound should still work. Or did I not understand your use case?

fzwoch commented 6 years ago

Ah I think this request for acting as an input device not a source. I need to check how that works inside OBS though..

fzwoch commented 6 years ago

Does such a thing exist in OBS studio? Looking around I figured - all plugins are global. I don't think I can add a "driver" to plug in into the desktop audio devices etc. The plugin code mentions audio in combination with video most of the time.. can elaborate what exactly you had in mind?

crossan007 commented 6 years ago

My use case: 32 channels coming in on USB from an audio mixer.

I want to prune off two of the channels to be used as a constant OBS audio source.

I could select the device from the normal OBS audio input device selector; however, that doesn't give me any control over which of the 32 channels are used in the 2 channel output

fzwoch commented 6 years ago

This sounds like a limitation on the OBS input selection then?

Alternatively you use this one but you would need to add it to every scene. But I don't see a way to "bridge" these two..

crossan007 commented 6 years ago

yeah - it would be nice if OBS allowed configurable mapping of audio inputs, or a plugin architecture for persistent audio inputs.

My current setup has this GST pipeline defined once in a scene, and then I include that scene in every scene that could go live.

There are two drawbacks with the "include everywhere" method:

fzwoch commented 6 years ago

If a scene includes two other scenes which have the GST pipeline included, there is a net audio volume gain of a few decibels.

I guess that's because the same audio is added twice and accumulates to some higher level audio?

f the GST pipeline was forgotten on a scene, then that will be a silent scene.

Not sure if I understand that one.

Perhaps the real solution would be to output the audio via gst-launch-1.0 to the regular sound device (or a virtual added one?) and let OBS pick that up via the default sound device settings?

crossan007 commented 6 years ago

I guess that's because the same audio is added twice and accumulates to some higher level audio?

I think that's what's going on.

If the GST pipeline was forgotten on a scene, then that will be a silent scene.

You might be over-thinking this one ;-) If I forgot to add the audio pipeline to a scene, then the audio obviously won't be in the mix, so the scene is silent.

Perhaps the real solution would be to output the audio via gst-launch-1.0 to the regular sound device (or a virtual added one?) and let OBS pick that up via the default sound device settings?

Yeah, this is probably better.

crossan007 commented 5 years ago

I've been looking through the OBS code on this issue, and made an interesting observation.

It looks like the "bundled" audio input sources (available from the OBS Settings | Audio menu are nothing more than standard OBS input plugins; however, the plugin available for use is hard-coded by a compile-time define statement: https://github.com/obsproject/obs-studio/blob/master/UI/obs-app.cpp#L1305

The name of the "selected" audio input plugin is serialized out to the DefaultCollection.json file in the OBS user directory by (https://github.com/obsproject/obs-studio/blob/master/UI/window-basic-main.cpp#L2238), and of specific interest is this: https://github.com/obsproject/obs-studio/blob/master/UI/window-basic-settings.cpp#L3270

I was able to copy/paste the JSON nodes for id as well as settings in my DefaultCollection.json file so that gstreamer-source may be used as an independent audio input without needing to add it as a sub-scene to all scenes that I want to use.

It's a bit hacky, but means that it may be relatively easy to extend the OBS window-basic-settings.cpp dialog to allow for additional "global" audio input plugins

With this, my DefaultCollection.json contains this:

{
    "AuxAudioDevice1": {
        "deinterlace_field_order": 0,
        "deinterlace_mode": 0,
        "enabled": true,
        "flags": 0,
        "hotkeys": {
            "libobs.mute": [],
            "libobs.push-to-mute": [],
            "libobs.push-to-talk": [],
            "libobs.unmute": []
        },
        "id": "gstreamer-source",
        "mixers": 255,
        "monitoring_type": 0,
        "muted": false,
        "name": "QU 32 MultiChannel Lines 31,32",
        "private_settings": {},
        "push-to-mute": false,
        "push-to-mute-delay": 0,
        "push-to-talk": false,
        "push-to-talk-delay": 0,
        "settings": {
            "pipeline": "videotestsrc pattern=18 ! video. alsasrc name=audiosrc device=hw:1 ! audio/x-raw,channels=32,layout=interleaved,rate=48000 ! queue ! deinterleave name=d interleave name=i d.src_30 ! queue ! audioconvert  ! i.sink_0  d.src_31 ! queue ! audioconvert  ! i.sink_1 i. ! audio. ",
            "restart_on_eos": true,
            "restart_on_error": true,
            "restart_on_update": true,
            "stop_on_hide": true,
            "sync_appsinks": true,
            "use_timestamps": true
        },
        "sync": 0,
        "volume": 1.0
    },

By hand-editing the JSON, we run the risk of losing the changes anytime the audio settings are changed, since the dialog box cannot resolve the source name: image

However, accessing the obs-gstreamer properties dialog box works as expected from the "gear" icon in the OBS audio mixer pane: image

Also of note is that any video written to obs-gstreamer's video. app sink will be overlaid on top of the final image. A curious side-effect that, while probably not intended, could actually be useful to someone, somewhere: image

fzwoch commented 5 years ago

Do you feel like moving this to the Wiki? :-)