I've ran Janus on a server and it works fine, but I'm kind of
struggling finding a way to stream on the Janus server, I could not
find any snippet code out there, I am developing with Vue.js, is there
any library to stream over Janus? I just need a sample.
Janus Gateway has a streaming plugin. You need to enable the plugin and use some software like gstreamer or ffmpeg to transfer video data to the streaming plugin.
The Q&A shows how to do this on Raspberry Pi.
https://superuser.com/questions/1458442/h264-stream-to-janus-using-ffmpeg-on-raspberry-pi
Short summary is below.
Set up Janus gateway streaming plugin
The streaming plugin configuration file is /opt/janus/etc/janus/janus.plugin.streaming.jcfg. (official documentation)
You can find there are several sample configurations. For example,
rtp-sample receives VP8/Opus video streaming data via RTP.
If you want to stream H.264 video, you can edit the configuration to add this setting.
h264-sample: {
type = "rtp"
id = 10
description = "H.264 live stream"
audio = false
video = true
videoport = 8004
videopt = 126
videortpmap = "H264/90000"
videofmtp = "profile-level-id=42e01f;packetization-mode=1"
secret = "somesecretid"
}
After editing the configuration, you need to restart Janus gateway.
Start video streaming
You can send video data to Janus streaming plugin via RTP. For example, if you have FFMpeg, you can do like this.
$ ffmpeg \
-f v4l2 -thread_queue_size 8192 -input_format yuyv422 \
-video_size 1280x720 -framerate 10 -i /dev/video0 \
-c:v h264_omx -profile:v baseline -b:v 1M -bf 0 \
-flags:v +global_header -bsf:v "dump_extra=freq=keyframe" \
-max_delay 0 -an -bufsize 1M -vsync 1 -g 10 \
-f rtp rtp://127.0.0.1:8004/
This command reads video data from /dev/video0 and
Please note the video parameters and output RTP port number (8084 in above example) should be corresponding to the Janus streaming plugin configuration.
Prepare Vue.js frontend
Next step is a frontend. You can create web frontend to view the streaming using janus.js bundled in Janus gateway. As described in the official documantation, you can use the janus.js as JavaScript module. But when you want to use it from Vue.js, you will need export-loader.
For example, you can create Vue.js2 project and add janus.js like this.
$ vue create mystreaming
$ cd mystreaming
$ yarn add git://github.com/meetecho/janus-gateway.git
$ yarn add exports-loader --dev
To add Webpack configuration, you need to create vue.config.js file with following content.
const webpack = require('webpack')
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({ adapter: 'webrtc-adapter' })
],
module: {
rules: [
{
test: require.resolve('janus-gateway'),
loader: 'exports-loader',
options: {
exports: 'Janus',
},
}
]
}
}
}
Then, you can import Janus object from Vue.js module like this.
import { Janus } from 'janus-gateway';
Then you can use janus.js and receive streaming video data using APIs.
I uploaded example Vue.js project, which might also help you.
Related
In case the lenght of the question might be scary, the summary of the question is how to interact with a front end app from a node server. Puppeteer usage should come along with that request solved I believe. Question is large because I explained all my failed attempts to achieve backend code (puppeteer) work in the browser. Apart from building and running the repo that although its easy right following the instructions might take a some time, I believe the question should be feasable for a javascript/node regular programmer. There it goes, thanks for reading.
I cloned, built and ran imgui-js repository succesfully.
I want to use it along with puppeteer for a small app. All the npm commands inside and stuff tried are inside the mentioned imgui-js project.
I tried:
1.- Run the node example from the project: With npm run-script start-example-node.
This runs the example/index.js script, but nothing is drawn as we are not in the browser and the window is undefined. Can be checked debugging in the main.ts:
if (typeof(window) !== "undefined") {
window.requestAnimationFrame(done ? _done : _loop);
}
So I do not understand the purpose of this example in the repo.
Edit: Seems it can be to have the client-server comunication done, but I do not now how to do this.
2.- Puppeteer browserify:
I followed the browserify hello world.
Just a summary of the steps:
npm install -g browserify
npm i puppeteer
Go to the build folder to generate de bundle.js for my const puppeteer = require('puppeteer'); script, so cd example, cd build, browserify myScript.js -o bundle.js
Add <script src="./build/bundle.js"></script> to the example/index.html.
I obtain this error:
Uncaught TypeError: System.register is not a function
at Object.96.puppeteer (bundle.js:19470:8)
at o (bundle.js:1:265)
at r (bundle.js:1:431)
at bundle.js:1:460
I also tried browserifying main.js along with my script: browserify main.js myScript.js -o bundle.js. Same error.
3.- Try to setup puppeter with the rollup module bundler: following this resource among others. So doing:
npm install --save-dev rollup tape-modern puppeteer
npm install --save-dev rollup-plugin-node-resolve
npm install --save-dev rollup-plugin-commonjs
npm install --save-dev sirv tape-browser-color
And tried to add that the the imgui-js rollup.config.js configuration file.
Think its not working because all the server setup at the npm start and so on is not performed with rollup.
4.- Puppeteer-web: Following the steps of this resource I tried to run puppeteer in the browser.
npm i puppeteer-web
Code in the client and the server:
Client:
<script src="https://unpkg.com/puppeteer-web"></script>
<script>
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://0.0.0.0:8080`, // <-- connect to a server running somewhere
ignoreHTTPSErrors: true
});
const pagesCount = (await browser.pages()).length;
const browserWSEndpoint = await browser.wsEndpoint();
console.log({ browserWSEndpoint, pagesCount });
</script>
Server (server.js script):
const httpProxy = require("http-proxy");
const host = "0.0.0.0";
const port = 8080;
async function createServer(WSEndPoint, host, port) {
await httpProxy
.createServer({
target: WSEndPoint, // where we are connecting
ws: true,
localAddress: host // where to bind the proxy
})
.listen(port); // which port the proxy should listen to
return `ws://${host}:${port}`; // ie: ws://123.123.123.123:8080
}
const puppeteer = require("puppeteer");
puppeteer.launch().then(async browser=>{
const pagesCount = (await browser.pages()).length; // just to make sure we have the same stuff on both place
const browserWSEndpoint = await browser.wsEndpoint();
const customWSEndpoint = await createServer(browserWSEndpoint, host, port); // create the server here
console.log({ browserWSEndpoint, customWSEndpoint, pagesCount });
})
Run server script: node server.js. Server seems properly created. Terminal log:
browserWSEndpoint: 'ws://127.0.0.1:57640/devtools/browser/58dda865- b26e-4696-a057-25158dbc4093',
customWSEndpoint: 'ws://0.0.0.0:8080',
pagesCount: 1
npm start (from new terminal to assure the created server does not terminate)
I obtain the error in the client:
WebSocket connection to 'ws://0.0.0.0:8080/' failed:
(anonymous) # puppeteer-web:13354
I just want to use puppeteer with this front end library together in my app, fetching data with puppeteer to display it the UI and provide the user input back to puppeteer.
My ideal solution would be number 1, where I would be able to use any npm package apart from puppeteer and communicate from the backend(node server) to the client (imgui user interface) back and forth.
Thanks for any help.
EDIT:
I more less achieved it with the node server solution server which is my desired scenario, with expressjs and nodemon, running a different server in the application and communicationg with the app. Now I would find more valuable any help on:
1.- The browserifying solution and or insight about why my attempts with this approach failed.
2.- The solution that keeps everything in the one same server, that would be the server that in the repo serves the html to the browser with "start-example-html": "http-server -c-1 -o example/index.html". Dont know if that is possible. Its because I would not lose the life loading etc if I serve both things with my expressjs server added by myself.
Kind of what Create React App does with Proxying API Requests
3.- As suggested in the comments, guidance or solution to make the server code render a window through node with the imgui output (npm start-example-node) of course would be a valid answer to the question.
Seems not quite correct to change the question conditions during the bounty with a bit of a broad new scenario, but now that conditions has changed so I try to make the most of the investment and the research already done in the topic, also due to my lack of expertise in the wev-dev module bundling configuration area, so bounty may be granted for the most valuable advice in any of the two topics mentioned above. Thanks for your understanding.
Important Detail & Workaround: I've come across this: "Deprecating Powerful Features on Insecure Origins"
This explains that HTTPS is enforced on external hosts. I have my development environment on my laptop and, on the weekend I SSH into that box, which is why I ran into this problem yesterday. I run the vuejs dev server remotely on the laptop, making it listen to 0.0.0.0 and open the page on my desktop. This causes the problem.
I've tried using SSH port forwarding to localhost. This worked and is an acceptable workaround for me.
The original question still remains valid. I will leave it open for now.
I'm working with a JS API which requires SSL (WebRTC). So to do development, I need to run the dev server over HTTPS. How can I do that with vuejs?
I've quickstarted the project using webpack. I found some links explaining how to run webpack-dev-server over SSL but I don't know how to do that with a vuejs application. I'm incredibly green considering everything that's JavaScript & NPM. The webpack links all mention a config file, but there is no such file in my project. The closest I see is the "main.js" but there is absolutely no configuration in there.
In essence, what I have is the result of the following steps:
mkdir demo
cd demo
npm install --save-dev vue-cli
./node_modules/.bin/vue init vuetifyjs/webpack-advanced demo
# Use the defaults here (except for "Vue build" I used "Runtime-only")
cd demo
npm install
npm run dev # <-- This is the command I would like to use SSL in
I don't know if you still have this problem or if any other person still encounters it but I found a solution.
Follow the instruction above to generate an openssl key and cert in your working folder.
In /node_modules/webpack-dev-server/bin/webpack-dev-server.js change this line from:
key: {
type: 'string',
describe: 'Path to a SSL key.',
group: SSL_GROUP
},
cert: {
type: 'string',
describe: 'Path to a SSL certificate.',
group: SSL_GROUP
},
to:
key: {
type: 'string',
describe: fs.readFileSync('key.pem'),
group: SSL_GROUP
},
cert: {
type: 'string',
describe: fs.readFileSync('cert.pem'),
group: SSL_GROUP
},
then set
argv.https = true;
That is all I had to do to have my code served from https.
Note that the command line will still read http://localhost:8080, but when you use https in the browser, your app will be displayed after warning from the browser
Requirement openssl installed :
First we have to generate SSL certificat based on a key made by openssl and without pass phrase cos this will generate an error.
nodejs https>node server.js
_tls_common.js:87
c.context.setKey(options.key);
^ Error: error:0907B068:PEM routines:PEM_READ_BIO_PRIVATEKEY:bad password read ...
Go inside your project start to create key & certificat :
openssl req -nodes -new -x509 -keyout key.pem -out cert.pem -days 365
-nodes : Don't encrypt the private keys at all.
Install the packages needed for your project : (--save to add to package.json)
npm install express --save
npm install https --save
npm install fs --save
now create the server file :
touch server.js
nano server.js
Copy/Paste : to server.js
var fs = require('fs');
var https = require('https');
var app = require('express')();
var options = {
key : fs.readFileSync('key.pem'),
cert : fs.readFileSync('cert.pem')
};
app.get('/', function (req, res) {
res.send('Hello World!');
});
https.createServer(options, app).listen(3000, function () {
console.log('Started!');
});
In this cas we don't use 443 port because is already used by services, so i use the port 3000 unused by any app...
I am new in the software field, please have patience with my question and mistakes of technical terms:
Premises:-
I have developed an front-end application using Angular4. The baseURL define in angular application is 'http://localhost:3000/'. My application uses restangular api to interact with json-server (I created a folder named json-server and it has db.json and public folder ). It is working perfectly fine when i start the json-server using command:
json-server json-server --watch db.json
My application is finalized and thus I created a production build. Thereafter I moved all my files from dist folder to public folder of json-server. When i start the json-server, my application works fine.
Actual problem:-
Now I wanted to host in azure. I simply copied all file/folder (db.json and public folder) from json-server folder as it is and put them in azure cloud. When azure hosting is done and I open the url in browser I got an error- "you don't have permission to view".
To rectify above error I deleted all files from azure and then I copied all files of dist folder and put them in azure cloud. Using this I could able to see the application in the browser but no images. At image there is an error- Response with status: 0 for URL: null
When I start json-server locally, everything works fine but of course when same web page open from other machines I got the same error- Response with status: 0 for URL: null
Is there any way to run json-server in azure so that all machines/mobile when accessing the url, can see proper web page without any error.
Step to step to run json-server on Azure Web App:
Open your browser and go to App Service Editor (https://<your-app-name>.scm.azurewebsites.net/dev/wwwroot/)
Run the command in the Console (Ctrl+Shift+C)
npm install json-server --save-dev
Put all file/folder (db.json and public folder) into wwwroot folder
Create a server.js with the following content
const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()
server.use(middlewares)
server.use(router)
server.listen(process.env.PORT, () => {
console.log('JSON Server is running')
})
Click Run (Ctrl+F5), this will generate web.config file automatically and open your website in the browser.
You can use the following to quickly setup a mock service which can serve REST APIs off static JSON files.
json-server
Just install the NodeJS module ($npm install -g json-server). Populate a static json file in the format attached and then run the JSON server ($ json-server --watch db.json --port 3000)
I need to build a meteor application under windows. How to do it right?
I found the meteor-electron package. If I understand correctly, it creates an executable file (exe).
I perform the following commands:
meteor create meteor-electron-build-test
cd meteor-electron-build-test
meteor add meson: electron
meteor
At this stage, everything is fine, the application of the electron inside the meteor is launched.
But if I stop the electron in the console and go to .meteor-electron \ win32-ia32 \ builds \ Electron-win32-ia32 \ Electron.exe - this application is empty.
I tried to add settings.
{
"electron": {
"name": "MyApp",
"version": "0.1.0",
"description": "A really cool app.",
"rootUrl": "https://myapp.com",
"launchPath": "/ app / landing",
"sign": "Developer ID Application: ...",
"height": 768,
"width": 1024,
"frame": true,
"title-bar-style": "hidden",
"resizable": true,
"protocols": [{
"name": "MyApp",
"schemes": ["myapp"]
}]
}
}
And launched the team meteor --settings settings.json. The result is the same.
https://github.com/StekolschikovV/meteor-electron-build-test
If I add the "appSrcDir" parameter: "./" - starts an endless loop that all copies to the .meteor-electron folder.
How to correctly build an executable file meteor electron using windows?
meteor-electron doesn't deliver a meteor server process, only a thin web client. Therefore, your rootUrl setting must point to a valid web address hosting your app. This can be http://localhost:3000 for the purposes of testing.
Try Electrify. I just tested it on the latest Meteor 1.7 and it works. Bundles node and MongoDB. Runs meteor client and server.
npm install -g electrify
https://github.com/arboleya/electrify
I have setup a cloudant local database using docker image.
When I try to send in a cloudant query using a JavaScript application hosted on localhost:8000 it gives me an CORS error.
How do I enable CORS on Cloudant local? I have tried the following
PUT request as described in https://docs.cloudant.com/cors.html#setting-the-cors-configuration
Checked the dashboard but the local instance does not have the "Account" tab available.
Same answer as #anirus, but there's a very kludgy way around it. If you have named the container cloudant-developer as in the current instructions at https://hub.docker.com/r/ibmcom/cloudant-developer/:
Save the stock default.ini file locally:
docker exec cloudant-developer cat /opt/cloudant/etc/default.ini > default.ini
Modify it so that enable_cors = true instead of false
In the [cors] section, add a line like origins = http://localhost:3000. It should also take a comma delimited list, but then you're probably only working on one app at a time.
Volume mount the modified default.ini over the original whenever you run the container by adding -v `pwd`/default.ini:/opt/cloudant/etc/default.ini to docker's list of command line arguments:
docker run --privileged --detach --volume cloudant:/srv -v `pwd`/default.ini:/opt/cloudant/etc/default.ini --name cloudant-developer --publish 8080:80 --hostname cloudant.dev ibmcom/cloudant-developer
This can be done using a custom Dockerfile which edits the Cloudant settings file before the database is started. I used this -
FROM ibmcom/cloudant-developer:latest
RUN \
sed -i 's/enable_cors = false/enable_cors = true/g' /opt/cloudant/etc/default.ini && \
sed -i 's/\[cors\]/\[cors\]\norigins=*/g' /opt/cloudant/etc/default.ini && \
sed -i 's/credentials = false/credentials = true/g' /opt/cloudant/etc/default.ini
It will enable cors with origins=* and also accept credentials from CORS connections.
You can put that in a Dockerfile, then docker build and docker run it.
All my investigation so far indicates that this is not supported on local Cloudant.