Ineed to know how to force exit the script when the log prints ERROR: RTMP_ReadPacket, failed to read RTMP packet header because I'm calling the script from PHP exec native function and is waiting forever for the exit code but the script does not return the exit code.
Since SimpleScreenRecorder uses ffmpeg/libav libraries to handle the encoding and formatting, it can also make use of ffmpeg/libav's ability to do live streaming. Live streaming is not my highest priority, but if you're interested in streaming and you need some specific feature, feel free to contact me.
You will need a pretty powerful computer to do live streaming. When you're just recording a video, the codecs are configured for high performance, which will increase the bitrate but reduce the CPU load. But when you're doing live streaming, the bitrate should be as small as possible, so this can't be done. So unless you have a really powerful processor, you shouldn't try to record at high resolutions.
Unfortunately, the streaming support in ffmpeg/libav isn't nearly as robust as the rest of ffmpeg/libav. RTMP streaming (explained below) appears to be reliable, but many other protocols and containers are not. Don't be surprised if SimpleScreenRecorder closes or freezes without any explanation. Some useful hints:
Not all containers are suitable for streaming. Some containers (e.g. MP4) put important metadata at the end of the file, so if you try to stream those files, you won't see anything. Containers that are known to work are 'flv' and 'mpegts' (found under 'Other'). Matroska also appears to work, but not all players support it.
In many cases, it takes some time before a stream starts playing, because the player has to wait for a keyframe. During this period you may even get error messages (e.g. complaining about missing frames). Wait at least 30 seconds before concluding that it doesn't work.
If you're using H.264, SimpleScreenRecorder will by default use 'constant quality mode'. This means the bitrate will vary depending on the complexity of the video. This is great for normal recording, where you only care about the total file size, but not so much for live streaming. You can get around this by setting the codec to 'Other', and then choosing 'libx264'. This is the same codec, but now it will be used with a fixed bitrate, which is better suited for streaming.
This is probably the simplest way to do streaming, but it also has some serious downsides. UDP is an unreliable transport system: packets can go lost and this will lead to corrupted video. This is not a problem when you're streaming over your LAN where packet loss is extremely unlikely, but if you stream over the internet, or even over a wireless connection, you will probably lose some packets.
You can then receive this stream in a video player like VLC or MPlayer. In VLC you would do this by clicking Media > Open Network Stream and entering udp://@:port. With some containers (e.g. flv), you should start the player before you start streaming to receive anything at all, while with other containers (e.g. mpegts) you can start the player whenever you want.
There's a utility called ffserver/avserver that can act as a streaming server for ffmpeg/libav. Theoretically it should be possible to make this work with SimpleScreenRecorder, but I haven't figured out how. The program is a bit weird, instead of just re-streaming whatever ffmpeg/libav sends to it, it actually tells ffmpeg/libav what format and codec it should use, and I have no idea how SimpleScreenRecorder is supposed to react to that.
The nice thing about RTMP is that the same protocol can be used not just to play a stream, but also to supply it. This means SimpleScreenRecorder can simply stream to rtmp://localhost:10200/live/nameofstream (just put that URL in the 'save as' field), and other clients will then be able to play that same URL. SimpleScreenRecorder doesn't need to act as a server and isn't exposed to the internet.
First you should set up the RTMP server. You have to compile nginx together with the RTMP module, instructions can be found at the github page for the RTMP module. Then you need to configure the server by modifying the nginx configuration file. All options are explained on the nginx and RTMP module websites. Here's the configuration that I used:
This tells nginx to run an RTMP server on port 10200 and an HTTP server on port 10201. The HTTP server hosts an HTML page (/live/live.htm) and the flash player (Flowplayer). Here's a simple example of what the HTML page could look like:
Nginx is set up so that every URL starting with /live/ gets redirected to that page, and then that page simply uses javascript to read the full URL and decide what stream should be played. If you go to :10201/live/nameofstream, it will stream from rtmp://localhost:10200/live/nameofstream.
The custom options field currently only supports 'private codec options', as ffmpeg calls them. You can use it to set x264 presets and tunings (try 'preset=fast,tune=zerolatency'). Generic options like 'keyint' don't work yet, I still have to add that.
Bit rates will always fluctuate, this is normal and even required for efficient use of bandwidth. You can make the bit rate more flat (at the cost of some quality) with the 'VBV' options, which correspond to rc_max_rate and rc_buffer_size in ffmpeg, but as with 'keyint' these won't work yet because they are not private codec options.
No, the ffmpeg command-line program is not used, I use the libraries directly. The libraries have a very different interface, unfortunately most of the options have different names and in some cases the names (or locations) have even changed between versions.
You have to realize that a perfectly constant bit-rate doesn't exist except for uncompressed streams. Even in CBR mode, you are going to see some variations over time. This is normal. If you set a bitrate in SimpleScreenRecorder, it will try to use that as the average bit rate, but it is possible that you will see peaks that are much higher than that. You can reduce the variations in bit rate with the VBV options I described, but this will greatly reduce the quality if you overuse it. And even then there are no guarantees.
First of all thanx for the livestreaming option. It's the only way i get a synced audio video stream to twitch.
Still a few questions are left:
1) You mentione VBV Options above, can you describe the usage a little more ?
The easiest way to do that is to just put a window there and mark it as 'always stay on top' in your window manager (usually by right-clicking the title bar). It is really hard to add something like this to SSR, and I still have a long to-do list at the moment (the feature request is already here).
I am trying to make this awesome program work with
twitch.tv but I can't for some reason.
I have pasted the rtmp link with the API key, I have set FLV as the container, set the encoder to libx264 (with ffmpeg) and audio encoder AAC at 64kbps but each time I press start recording, I get:
I'm not 100% sure, but it sounds like they were just doing their timestamps wrong. SSR uses the encoder time base to encode the frames and then converts the timestamps to the stream time base when muxing. This is what the ffmpeg/libav example code does too.
If you use ffmpeg with -maxrate 500k -bufsize--500k it never goes over the 500kbit/s. It instead adapts the crf / qp to fit the stream. When i do the same with the actual solution it spikes up to 800kbit/s end even 900kbit/s on simple screen recorder side.
This may be related to the way the bitrate is calculated. I calculate the bitrate manually simply by checking the number of bytes written and the timestamps of the packets. This is often inaccurate but I couldn't find a better solution. On average it is still correct though.
But even with ffmpeg, it is perfectly possible that the bitrate will occasionally go above 'maxrate' if it has stayed below 'maxrate' for some time. This is normal. The 'bufsize' indicates how much variation is allowed (in practical terms, it indicates how much memory the receiver will need to buffer the stream assuming a perfectly constant download speed equal to 'maxrate').
So in other words, as long as the download speed is at least 'maxrate', and the receiver has a buffer of at least 'bufsize', the stream will play fine even when the bitrate peaks above 'maxrate' occasionally. If you set 'bufsize' equal to 'maxrate', this corresponds to a one-second buffer. Most players will buffer the stream for a few seconds before they start playing, so this is fine.
Also, i was curious if you can incorporate UVC webcam captures at the same time. There's already a script here: that has both screen capture and webcam capture. Whats nice about the script also is that if you want to record a window versus your whole desktop, you merely click the window you want to record instead of having to find out the window info using some command line tool. Since I am asking about features, can you somehow adapt the input to be able to record other things besides your desktop, for example a webcam or a device node? I have an HD-PVR which I capture by just using the terminal and issuing cat /dev/video1 > video.ts and it captures my xbox 360 into a file using h264 and aac audio in a mp4 container, is there some way your program could capture HD-PVR over usb and re-encode it for optimal streaming experience?
Whats nice about the script also is that if you want to record a window versus your whole desktop, you merely click the window you want to record instead of having to find out the window info using some command line tool.
3a8082e126