0

I'm trying to stream my Gnome Desktop I installed on my OpenVZ VPS Server, and I'm not trying to run this from SSH, but the terminal inside the GNOME desktop,

I know it probably doesn't have a sound card, but it's not like i'm trying to play the sound, I just want to route it to the stream.

Inside my PulseAudio Volume Control volume control

Here is how it looks like when I attempt to stream it. ffmpeg

More stuff I tried more errors happened here more errors about alsa, soundcards

Here is when I run the pacmd list-source-outputs

[removed@removed ~]$ pacmd list-source-outputs
Welcome to PulseAudio! Use "help" for usage information.
>>> 2 source outputs(s) available.
    index: 0
    driver: <protocol-native.c>
    flags: DONT_MOVE 
    state: RUNNING
    source: 0 <auto_null.monitor>
    current latency: 3.08 ms
    requested latency: 20.00 ms
    sample spec: float32le 1ch 25Hz
    channel map: mono
                 Mono
    resample method: peaks
    owner module: 6
    client: 4 <PulseAudio Volume Control>
    properties:
        media.name = "Peak detect"
        application.name = "PulseAudio Volume Control"
        native-protocol.peer = "UNIX socket client"
        native-protocol.version = "16"
        application.id = "org.PulseAudio.pavucontrol"
        application.icon_name = "audio-card"
        application.version = "0.9.10"
        application.process.id = "997"
        application.process.user = "removed_for_stackexchange(wasn't root)"
        application.process.host = "removed_for_stackexchange"
        application.process.binary = "pavucontrol"
        window.x11.display = ":1.0"
        application.language = "en_US.UTF-8"
        application.process.machine_id = "27be3273f5d5332051ccdc3100000002"
        application.process.session_id = "27be3273f5d5332051ccdc3100000002-1394085585.776225-694791372"
        module-stream-restore.id = "source-output-by-application-id:org.PulseAudio.pavucontrol"
    index: 1
    driver: <protocol-native.c>
    flags: DONT_MOVE 
    state: RUNNING
    source: 0 <auto_null.monitor>
    current latency: 3.11 ms
    requested latency: 20.00 ms
    sample spec: float32le 1ch 25Hz
    channel map: mono
                 Mono
    resample method: peaks
    owner module: 6
    client: 4 <PulseAudio Volume Control>
    direct on input: 2
    properties:
        media.name = "Peak detect"
        application.name = "PulseAudio Volume Control"
        native-protocol.peer = "UNIX socket client"
        native-protocol.version = "16"
        application.id = "org.PulseAudio.pavucontrol"
        application.icon_name = "audio-card"
        application.version = "0.9.10"
        application.process.id = "997"
        application.process.user = "removed_for_stackexchange(wasn't root)"
        application.process.host = "removed_for_stackexchange"
        application.process.binary = "pavucontrol"
        window.x11.display = ":1.0"
        application.language = "en_US.UTF-8"
        application.process.machine_id = "27be3273f5d5332051ccdc3100000002"
        application.process.session_id = "27be3273f5d5332051ccdc3100000002-1394085585.776225-694791372"
        module-stream-restore.id = "source-output-by-application-id:org.PulseAudio.pavucontrol"

More information about sink i'm using

[removed@removed ~]$ pacmd list-sinks
Welcome to PulseAudio! Use "help" for usage information.
>>> 1 sink(s) available.
  * index: 0
    name: <auto_null>
    driver: <module-null-sink.c>
    flags: DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY
    state: RUNNING
    suspend cause: 
    priority: 1000
    volume: 0: 100% 1: 100%
            0: 0.00 dB 1: 0.00 dB
            balance 0.00
    base volume: 100%
                 0.00 dB
    volume steps: 65537
    muted: no
    current latency: 3.49 ms
    max request: 3 KiB
    max rewind: 3 KiB
    monitor source: 0
    sample spec: s16le 2ch 44100Hz
    channel map: front-left,front-right
                 Stereo
    used by: 1
    linked by: 3
    configured latency: 20.00 ms; range is 0.50 .. 10000.00 ms
    module: 9
    properties:
        device.description = "Dummy Output"
        device.class = "abstract"
        device.icon_name = "audio-card"
1

(hopefully) IMPROVED CODE AT BOTTOM

Reading the script provided in your own answer, I've reached the following conclusions about your solution. Please correct me on any/all mistakes I might have made.

You append an xwininfo $GAME_WINDOW-specific dataset to a tmpfile dump after specifying $GAME_WINDOW's geometry via wmctl. Before initiating the dump you effectively truncate your tmpfile to 0-bytes with rm -f which presumably occurs only once per session either because the stream is session-specific or to avoid the tmpfile growing too large, though, again, I'm presuming both. I base the above conclusions on these three lines:

> rm -f twitch_tmp 2> /dev/null
> wmctrl -r "$GAME_WINDOW" -e 0, 411,51,160,144
> xwininfo -name "$GAME_WINDOW" >> twitch_tmp

While I'm not intimately familiar with either wmctl or xwininfo I do know that they're common xorg utilities for automating various X window behaviors. I'm assuming you're streaming that dataset just to keep up with any changes as they might occur so ffmpeg can do the right thing with its transcode rather than actually pumping the actual graphic/sound source data through the following two environment variables as I doubt very seriously the latter behavior would work for any more than a few seconds if at all:

> TOPXY=$(cat twitch_tmp | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )
> INRES=$(cat twitch_tmp | grep -oEe 'geometry [0-9]+x[0-9]+' | grep -oEe '[0-9]+x[0-9]+')

Here you:

  • Open two $(command substitution) subshells, one each for $TOPXY and $INRES value assignments.

For $TOPXY you:

  • Concatenate your tmpfile with stdin and anonymously |pipe the results to grep's stdin which then ...
  • oEe Omits any line and any portion of any line not thereby omitted which does not contain the string:
    • "Corners:" followed by ...
    • at + least one \s whitespace character, then ...
    • a \+ literal plus sign, then ...
    • at + least one [0-9] digit ...
    • another \+ literal plus ...
    • and, finally, at least + one more [0-9] digit ...
  • The results are anonymously |piped to another instance of grep which subsequently -oEe omits everything before your first captured [0-9] digit then anonymously |pipe its results to ...
  • sed which transforms all literal \+ pluses it receives to , commas and dumps to its stdout which is ...
  • finally captured and stored in $TOPXY via the $(command substituted) subshell variable assignment.

The process for $INRES appears much the same, if a little less complex.

Most noteworthy to me is that the entire tmpfile is concatenated at least twice for every invocation, which is not to mention all of the |pipes. Probably there are a lot of ways to do this, but I can't imagine this would be among the better of them.

After this you invoke ffmpeg referencing the two variables above and various other options including other environment variables you've also specified:

ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i $DISPLAY+$TOPXY \
    -f pulse -i default \
    -vcodec libx264 -preset $PRESET -crf 30 -x264opts keyint=50:min-keyint=20 -s $INRES \
    -acodec libmp3lame -ab $AUDIO_BITRATE -ar $AUDIO_RATE_HZ \
    -threads 0 -pix_fmt yuv420p \
    -f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"

PROBABLY MORE DIRECT

What follows involves no tmpfiles, a single |pipe, calls only a single invocation of sed and a single subshell command substitution for parsing your geometry settings, and is contained in a single function. All of the environment variables are defined in here-documents streamed to its stdin and are therefore effectively locally scoped. They are also defined via parameter-substitution and are therefore configurable. For instance to alter the value of $FPS for a single invocation you need only do:

% FPS=28 desk_stream

For what it's worth, though, I still think vlc would make a much better option.

desk_stream() { sed -rn '\
    /.*((Corners:|geometry)\s*\+*([x|+|0-9]*\+)).*/{\
        s//\3/;\ 
            /X/s/.*/\
                    INRES="&";/p;\
                s/(.*)\+(.*)\+$/\
                    DISPLAY='"${DISPLAY}"'"+\1,\2,";/p;\
    };$a\. 0<&3 /dev/stdin\n' | . /dev/stdin
} <<FFOPTS 3<<-\FFCMD
${FPS="15"}                                    # target FPS
${PRESET="ultrafast"}                    # one of the many FFMPEG preset on (k)ubuntu found in /usr/share/ffmpeg
${THREADS="0"}                 #0 autostarts threads based on cpu cores.
${AUDIO_BITRATE="1k"}               #Audio bitrate to 96k
${AUDIO_RATE_HZ ="44100"}       #Audio rate 44100 hz
${GAME_WINDOW="MYGAMETEST"}
${STREAM_KEY=live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx}
${SERVER="live-jfk"}    # NY server
$(wmctrl -r "$GAME_WINDOW" -e 0, 411,51,160,144 &&\
      xwininfo -name "$GAME_WINDOW")
FFOPTS
ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i $DISPLAY \
        -f pulse -i default \
        -vcodec libx264 -preset $PRESET -crf 30 -x264opts keyint=50:min-keyint=20 -s $INRES \
        -acodec libmp3lame -ab $AUDIO_BITRATE -ar $AUDIO_RATE_HZ \
        -threads 0 -pix_fmt yuv420p \
        -f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"
FFCMD        
1

So you've definitely got pulseaudio installed, but you are apparently missing the ALSA pulseaudio emulation drivers. Pulseaudio is interfaced by client apps in a lot of different ways, but a common one is for the applications to address ALSA and pulseaudio to intercept. Alsamixer evern works this way on a properly configured system. Here is a very useful page for understanding the way pulseaudio works. In particular, it has this to say on module-alsa-sink:

You should (almost) never have to load this module manually.

You might be interested in the module a couple lines up there, module-pipe-{sink,source}:

Provides a simple test {sink,source} that {writes,reads} the audio data {to,from} a FIFO...

To that end, if you've got VLC, or can get it, you might try streaming with it:

pacmd list-source-outputs

should contain an output address something like what I've pasted in below for your dummy source:

cvlc pulse://alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor \
    --sout '#transcode{acodec=mpga,ab=128,channels=2}:\
     standard{access=http,dst=0.0.0.0:8080/pc.mp3}' &

Oh, and you might also have some interest in pacat and you've probably already got it. It's the single executable that both parec and paplay link to.

A little more on Pulse/ALSA (though they're documentation is pretty good on this):

Pulseaudio attempts to imitate ALSA for any application that hasn't yet been updated to interface it. Basically the theory goes that if an application isn't equipped to do dbus it with pulse, pulse will middleman ALSA anyway via the module-alsa-sink plugin interface I mentioned before. In fact, the same is true for OSS and Esound and their respective modules if they should be required.

But maybe you're overthinking this - the simplest sound streaming can be accomplished with mkfifo, or even just cat, should you desire. Depending on your bandwidth and latency requirements netcat could be pretty useful here. You could also look in to Sox - it offers an interface similar to pacat.

What is your linux distribution? I understand its in a container, but verifying you've updated all relevant packages is probably called for here, especially if pulse isn't running. Try this:

pulseaudio --start

If it runs, try this for maybe a better hint at what your source might be:

pacmd list-source-outputs | grep 'source:'
  • pacat Connection failure: Connection refused pacmd No PulseAudio daemon running, or not running as session daemon. lol who knows why the sound sliders move. Actually it used to work.. must of crashed, how do I make pulseaudio a service? or i should just restart the server – SSpoke Mar 6 '14 at 5:47
  • Do I need VLC? can I set it up with ffmpeg some how? I been researching for hours now best thing I found was to use jack-capture to dump speakers to file. pacmd idea sounds better if I can link it up with ffmpeg – SSpoke Mar 6 '14 at 5:51
  • What is ALSA pulseaudio emulation drivers I can't find these is there a yum command for this? – SSpoke Mar 6 '14 at 5:56
  • added lots of outputs for pacmd list-sinks and pacmd list-source-outputs in question – SSpoke Mar 6 '14 at 6:14
  • 1
    I'm on my laptop - I don't even know if it has sound configured either, never checked. BUT it did attempt to send me a file (the pipe-stream) which I cancelled immediately to come here to tell you to turn that off. I'm sorry, man, but I don't have anymore advice. – mikeserv Mar 6 '14 at 9:53
0

Solved the problem myself, This below works perfect even without a sound card on your VPS, it streams desktop both audio and video.

FPS="15"                                    # target FPS
PRESET="ultrafast"                    # one of the many FFMPEG preset on (k)ubuntu found in /usr/share/ffmpeg
THREADS="0"                 #0 autostarts threads based on cpu cores.
AUDIO_BITRATE="1k"               #Audio bitrate to 96k
AUDIO_RATE_HZ ="44100"       #Audio rate 44100 hz
GAME_WINDOW="MYGAMETEST"
STREAM_KEY=live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
SERVER="live-jfk"    # NY server

rm -f twitch_tmp 2> /dev/null
wmctrl -r "$GAME_WINDOW" -e 0, 411,51,160,144
xwininfo -name "$GAME_WINDOW" >> twitch_tmp
TOPXY=$(cat twitch_tmp | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )
INRES=$(cat twitch_tmp | grep -oEe 'geometry [0-9]+x[0-9]+' | grep -oEe '[0-9]+x[0-9]+')

ffmpeg -f x11grab -s "$INRES" -r "$FPS" -i $DISPLAY+$TOPXY \
             -f pulse -i default \
             -vcodec libx264 -preset $PRESET -crf 30 -x264opts keyint=50:min-keyint=20 -s $INRES \
             -acodec libmp3lame -ab $AUDIO_BITRATE -ar $AUDIO_RATE_HZ \
             -threads 0 -pix_fmt yuv420p \
             -f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.