RTMP video with emscripten C/C++ to Javascript LLVM compiler - javascript

I understand emscripten is a super powerful way to encode C code into Javascript.
Is it possible to use this for video, capture the webcam and stream this over RTMP using something like the rtmpdump library?

rtmpdump can be recompiled to javascript using Emscripten. However, that does not guarantee that the recompiled code is capable of executing within a Javascript environment in the way that the RTMP spec requires (namely the requirement for TCP).
Steps used to recompile rtmpdump with Emscripten:
Obtain latest portable emscripten tools:
Obtain rtmpdump source:
git clone git://git.ffmpeg.org/rtmpdump
Clear make cache
make clean
Set C compiler to CC in Makefile
Edit the rtmpdump Makefile on line 5 to the following:
CC=$(CROSS_COMPILE)cc
Run emmake to create bytecode from make output:
emmake make CRYPTO=
(Per rtmpdump README, I opted to use 'CRYPTO=' to build without SSL support as it was giving errors)
Run emcc to compile and link resulting bytecode into javascript:
emcc -01 ./librtmp/*.o rtmpdump.o -o rtmpdump.js
Run the recompiled rtpmpdump.js:
chmod 755 rtmpdump.js
node rtmpdump.js -r rtmp://127.0.0.1/live/STREAM_NAME
Of course, we will need a live RTMP stream to test against.
Steps to create live RTMP stream:
Obtain latest node-rtsp-rtmp-server:
git clone
https://github.com/iizukanao/node-rtsp-rtmp-server.git
Add an mp4 to livestream over RTMP:
(Using Big Buck Bunny as our test video)
cd node-rtps-rtmp-server/
npm install -d
cd file/
wget http://download.bl4ender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4
Start the RTMP server
sudo coffee server.coffee
Publish mp4 to RTMP server with ffmpeg
ffmpeg -re -i /node-rtsp-rtmp-server/file/BigBuckBunny_320x180.mp4 -c:v copy -c:a copy -f flv rtmp://localhost/live/STREAM_NAME
Observations
You should be able to confirm that the RTMP stream is successfully published by connecting with something like VLC Media Player. Once we confirm the stream is properly running, we can test rtmpdump.js with:
node rtmpdump.js -4 rtmp://127.0.0.1/live/STREAM_NAME -o out.flv
However, we immediately encounter:
ERROR: RTMP_Connect0, failed to connect socket. 113 (Host is unreachable)
Conclusion
While my answer explores a path to recompiling rtmpdump and it's supporting libraries (librtmp) to Javascript, it does not produce a working implementation.
Some quick research concludes that RTMP relies on TCP communication for transmission from server to client. Javascript by nature, confines communication to XHR and WebSocket requests only. The steps I have outlined for recompilation of rtmpdump produces XHR requests for the RTMP_Connect0 method which are HTTP based (i.e. != TCP). It may be possible to rewrite an RTMP client to use websockets and pass those connections over to TCP using something like WebSockify, however, if successful you would move the RTMP's dependency on flash to a dependency on Websockify if you intend to consume an RTMP stream. Producing a flashless RTMP client does not appear to be a simple matter of recompiling RTMP to Javascript as the transport mechanism (TCP) must be accounted for.
Notes
For anyone looking to pick up on this work, be aware that testing against a remote stream from a browser running a theoretically proper rtmp implementation in Javascript would require that CORS is enabled on the remote host due to Same-Origin-Policy. See: https://github.com/Bilibili/flv.js/blob/master/docs/cors.md

Related

Creating a NodeJS based web server to take advantage of HTTP2 on windows platform

I am using windows 2012 server and want to host some static HTML/CSS/JS/image files on a nodejs based web server. I do not want to use IIS as I want to take advantages of HTTP2 & want to push files from server to client. I looked at Using node.js as a simple web server which talks about how to create a node based webserver. Another option is to use http-server node package.
My question is:
These solutions are over two year old. Do we have a better option available now?
Does any of these two options supports HTTP2?
I would prefer using a existing node module rather then reinventing the wheel.
You could try NGINX, it can support HTTP/2. http://nginx.org/en/docs/windows.html
Run your node applications by using default node, nodemon, pm2...
Then use NGINX as a static web server and you can reverse proxy your node apps.
If you want to use Node then this article seems to cover the basics: https://webapplog.com/http2-server-push-node-express/ and it seems the node-spdy module is the best option (it includes support for HTTP/2 despite the name). There is a node-http2 module but it seems much less well maintained and doesn't support Express (the most popular HTTP framework for Node).
However, as discussed in the comments, while not the question you asked, I recommend running a traditional web server (e.g. Apache, Nginx or IIS) in front of NodeJS or any other traditionally back end server. While NodeJS is very flexible and most (if not all) of the functionality of a webserver can be added to it, a traditional web server comes out of the box with a lot of functionality and requires just configuration rather than programming and/or pulling in multiple other modules to set it up properly.
For just serving static files Node seems the wrong solution to me so, for the rest of my answer I'll discuss not not using Node directly for the reasons given above but instead using a front end webserver.
I don't know IIS too well but from a quick Google it seems HTTP/2 was only introduced in IIS 10 and, as far as I know, even IIS 10 doesn't support Push except through API calls so I agree with your decision not to use that for now.
Nginx could be installed instead of IIS, as suggested, and while it supports HTTP/2 it doesn't yet support HTTP/2 (though Cloudflare have added it and run on Nginx so imagine it won't be long coming).
Apache fully supports HTTP/2 including server push. Packaged windows versions of Apache can be downloaded from Apache Lounge so is probably the easiest way of supporting HTTP/2 push on Windows Server and would be my recommendation for the scenario you've given.
While I mostly use Apache on Linux boxes I've a number of servers on Windows and have quite happily been running Apache on that as a Service (so it automatically restarts on server reboot) with no issues so not sure what "bad experience" you had previously but it really is quite stable to me.
To set up Apache on a Windows Server use the following steps:
Download the last version from Apache Lounge.
Unzip the files and save them to C:\ (or C:\Program Files\ if you prefer but update all the config to change the default C:\apache24 to C:\Program Files\)
Edit the conf\httpd.conf file to check ServerRoot, DocumentRoot and any Directory values are set to where you want it (C:\Apache24 by default).
Run a DOS->Command Prompt as Administrator
In the Administrator CD to the Apache location and the bin director.
Run httpd.exe and deal with any error messages (note port 80 must be free so stop anything else running on that report).
Check you get the default "It works!" message on http://localhost/
Install Apache as a service by killing the httpd.exe process and instead running httpd.exe -install.
Start the Apache24 service and again verify you get the "It works!" message on http://localhost/
To add HTTP/2 and HTTPS (necessary for HTTP/2 on all browsers), uncomment the following lines from httpd.conf:
LoadModule http2_module modules/mod_http2.so
...
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
...
LoadModule ssl_module modules/mod_ssl.so
...
Include conf/extra/httpd-ssl.conf
Install a cert and key to conf/server.crt and conf/server.key - note Apache 2.4 expects the cert file to include the cert plus any intermediary certs in X509 Base 64 DER format so should look something like this when opened in a text editor:
-----BEGIN CERTIFICATE-----
MII...etc.
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MII...etc.
-----END CERTIFICATE-----
Where the first cert is the server cert and the 2nd and subsequent certs are the intermediaries.
You should make sure you're running good HTTPS config (the defaults in Apache are very poor), but the defaults will do for now. I've a blog post on that here.
Restart Apache in the service menu and check you can access https://localhost (ignoring any cert error assuming your cert does not cover localhost).
To add HTTP/2 to Apache
Edit the conf/extra/httpd-ssl.conf file to add the following near the top (e.g. after the Listen 443 line):
Protocols h2 http/1.1
Restart Apache in the service menu and check you can access https://localhost (ignoring any cert error assuming your cert does not cover localhost) and you should see h2 as the protocol in the developer tools of your web browser.
To use HTTP/2 push in Apache add the following to push a style sheet:
Header add Link "</path/to/css/styles.css>;rel=preload;as=style" env=!cssloaded
And you should see it pushed to your page in developer tools. Again, I've a blog post on that if you want more information on this.
If you do want to use Node for some (or all) of your calls you can uncomment the following line from conf/httpd.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
And then add the following config:
ProxyPass /nodecontent http://127.0.0.1:8000/
Which will send any of those requests to node service running on port 8000. Restart to pick up this config.
If your node service adds any HTTP headers like this:
link:</path/to/style/styles.css>;rel=preload;as=style
Then Apache should pick them up and push them too. For example if using Express you can use the following to set the headers:
app.get('/test/', function (req, res) {
res.header('link','</path/to/style.css>;rel=preload;as=style');
res.send('This is a test page which also uses Apache to push a CSS file!\n');
});
Finally, while on the subject of HTTP/2 push this article includes a lot of interesting food for thought: https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/
I know this is a fairly old question, but I thought I would give an answer for those that come here looking for info.
Node now has a native http2 module and there are some examples on the web that show exactly how to implement a static web server.
NOTE: At the time of this answer Node 9.6.1 is current and the native module is still experimental
Example https://dexecure.com/blog/how-to-create-http2-static-file-server-nodejs-with-examples/
NOTE: I have no affiliation to the author of the example

How to use a browser on a remote server for an automated tests

I inherited a project where the person wrote tools to test our site's UI using JQuery and JS.
I don't know too much about it other than it requires a browser to be spawned and I think the tool uses JS to interact with iframes to see if it's the expected values.
My job is to get this tool to run on a remote server and post the results to Jenkins.
The remote test server and staging server is linux. From our staging server, I want to write a script to spawn a browser and run cmds from the tool to test our UI. I ran the following manually:
ssh -X user#remote_test_server /usr/bin/firefox
However, the remote server says:
Error: no display specified
Is there a way to spawn a browser for automated testing from one headless server to another? Thanks in advance for your help.
I faced a similar problem when I tried to automate a GUI installation program. While there are quite some different possibilities to choose from (e.g. Xnest, Xephyr?), I ended up using vncserver, because it's relatively easy to debug the GUI session this way.
You need to create a vncpassword file, I think:
mkdir -p $HOME/.vnc
chmod 0700 $HOME/.vnc
echo MyLittlePassword | vncpasswd -f > $HOME/.vnc/passwd
chmod 0600 $HOME/.vnc/passwd
Starting the server is then quite straightforward
vncserver
export DISPLAY=:1
/usr/bin/firefox&
...
Now it is possible to connect to the VNC server with a VNC viewer of your choice. But beware there may be no window manager, depending on the X startup scripts of your environment.
Shutting the server down
vncserver -kill :1
In the configuration of Jenkins project , specify the
Build Environment
Start Xvfb before the build, and shut it down after.
#

How to build OpenCV for PNaCl on Windows

I'm beginner to PNaCl/NaCl and have a problem.
I want to use "openCV" on Web Native Client. So I tried to build "naclports" on cygwin.
But it was failed..
below is my workflow and result. Please tell me what is wrong or alternative idea to use "openCV".
*I use windows8.1 and cygwin.
1. Download and install the [Native Client SDK][1].
- installed pepper version is 35. PATH is C:/cygwin64/home/*user*/nacl_sdk/pepper_35 (set the environment variable).
2. Clone the "[naclports][2]" in C:/cygwin64/home/*user*/naclports/src/
3. Done the build on cygwin.
**#** ~/naclports/src
$make opencv
4. error is coming:
######################################################################
Testing zlib
######################################################################
chdir /home/ryosuke/naclports/src/out/build/zlib/zlib-1.2.8
DEBUG MODE ENABLED (bypass acl)
fread: Broken pipe
DEBUG MODE ENABLED (bypass acl)
NaClMain: <fd:0>: Broken pipe
*** minigzip test FAILED ***
naclports: Building 'zlib' failed.
Makefile:68: recipe for target 'opencv' failed
make: *** [opencv] Error 1
Do you have any good idea?
Unfortunately many of the ports in naclports don't currently building cygwin. In this case you can see that its actually zlib that is failing to build.
If possible you can build the ports a mac or linux machine and copy the resulting packages over.
A system for installing binary package is currently being developed to make it easier to install pre-built packages rather than building them from source.

Installing NodeJS and SocketIO in a Remote Server

My project is a Real Time Two-Player Facebook Game, and what I need is a tool that will help me build the game with quick responses to enable the "Real Time" function of the game. I have just found out about the Node JS and Socket IO. I have some knowledge in JavaScript so I stepped up and watched a few tutorials that discuss the functions of Node JS and Socket IO.
Here's the link to the videos that I have watched:
http://www.youtube.com/watch?v=mSE6xHkcX0w
I understand the basic of the Node JS and Socket IO and successfully installed it in my localhost. The problem is when I uploaded the files from my localhost to my remote server, some functions of the program are not working well. I don't know how to node my JavaScript file when it is on the server, because if it's in my localhost, I am using command prompt to run it.
node app.js
Node is not a web framework.
Chances are, you're using a web host that's generalized for web frameworks like PHP and Ruby on Rails. You're going to need virtual private server hosting, or Node-specific hosting, because Node requires a virtual machine to run. You otherwise won't be able to run Node Package Manager or Node itself.
Joyent has provided a list of hosts here.
If you chose to use a VPS or dedicated machine, an installation guide would be found here. This is how you would install Node on CentOS.
wget http://nodejs.org/dist/v<version>/node-v<version>.tar.gz
tar -zxf node-v<version>.tar.gz
cd node-v<version>
./configure
make -j <number of cores>
make install

Installing/setting up Socket.IO on my server

Ok so I have read through the Socket.IO docs and I am still a little unsure of a couple of points:
The documentation says...
To run the demo, execute the following:
git clone git://github.com/LearnBoost/Socket.IO-node.git socket.io
cd socket.io/example/
sudo node server.js
Now I don't know what this means at all! I think it may be command line interface. I of course have access to this on my localhost, but my online hosting package is a shared LAMP setup. Meaning I don't have access to the root command line (i think).
How do I actually setup socket.IO, is it impossible on my shared server package?
Appreciate any help...
W.
If you aren't familiar with node.js or with basic command line usage then I would suggest that you use a hosted WebSockets solution like pusherapp. Trying to learn WebSockets, and Node.js, and the Linux command line all at once is going to lead to a lot of frustration. Take a look a pusherapp's quick start guide, it's very easy to get started. You can have 5 simultaneous connections with a single application for free (I'm not affiliated with pusherapp).
Updated (with inline answers to questions):
If you are going to go the direction of running a Socket.IO application:
You don't technically need git since you can download node.js and Socket.IO from their respective download links on github.
You don't actually need a LAMP server to use Socket.IO. By default Socket.IO functions as a simple webserver in addition to a WebSockets server. If you want server side scripting then you might want Apache with mod_php, mod_python, etc.
You don't technically need a dedicated server or even root access. You do need a system where you can have long running process. And if you want the service to start automatically when the system is rebooted, you probably want to add a startup file to /etc/init.d, /etc/rc.d which will require root access. Both node.js and Socket.IO can be installed and run from a normal home directory. If you want to run Socket.IO on a standard port like 80 or 443 then you will need to run it with root privilege.
Node.JS scales quite well so Socket.IO will probably scale pretty well too.
It's not a simple matter to get everything setup and working, but if your goal is a free solution for web serving+WebSockets then Socket.IO is probably is good route to at least explore if you are brave.
First you'll have to determine if your host supports SSH. Sometimes they don't by default on shared hosting, but if you ask they can turn it on. If it does you'll use some sort of SSH client to connect to it. Putty for windows is the most common. Then you'll use git, which is a source control program. Which you'll probably have to install on your host, which may or may not be allowed. If you can, this can be accomplished a number of ways, you'll want to read the git documentation, it will depend largely on what linux distribution you're running. CD is change directory, basic command line stuff. sudo on the last line is telling the system to run the command as root, which it will ask you the password for, which you may not have access to on your host. Sounds like you're gonna have an uphill battle on shared hosting. You may want to opt for a VPS instead.
If your shared host is a LAMP system with no command line access you're not going to get very far with Socket.IO. The instructions you posted assume you have command line access and that you've installed the node.js runtime on your system.
If you really want to try this I recommend you get a VPS of your own (I use prgmr.com) to test it out. For what it's worth I found the Socket.IO platform pretty nice to use once I got it up and running.

Categories