RTSP (video stream) in Electron - electron

I've installed fluent-ffmpeg and ffmpeg-static to convert a stream into an HTML reproducible video. How can I use these packages to display the stream in the client?
Server side (main.js):
const { app, BrowserWindow } = require('electron');
const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('ffmpeg-static').replace('app.asar', 'app.asar.unpacked');
ffmpeg.setFfmpegPath(ffmpegPath);
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile('index.html');
}
function testStream () {
let source = 'rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov';
}
app.whenReady().then(createWindow).then(testStream);
Client side (index.html):
<!DOCTYPE html>
<html>
<head>
<meta charset = 'UTF-8'>
</head>
<body>
<h1>I want to reproduce the video here</h1>
</body>
</html>

If I understand correctly; you're probably looking to start with something like this:
<video id="video-player" controls preload="none" style="border: 5px solid red; height: 1080px; width: 1920px; ">
<source src="index.m3u8" type="application/x-mpegURL">
</video>

Related

Can change video quality settings for some Vimeo videos only in iOS

Some of my Vimeo videos rendered in the iOS web view show the quality settings to toggle between different qualities. But in other videos, I can only see 360p quality. Is there any specific reason for this behavior?
I can toggle between qualities inside the Android Web view.
I'm using a React Native Web View to render the Vimeo player.
My web view template
<html>
<head>
<meta name="viewport" content="width=device-width initial-scale=1.0 maximum-scale=1 user-scalable=0 minimum-scale=1">
</head>
<body style="width: 100%; height: 100%; margin: 0;">
<div style="width: 100%; height: 100%;">
<div id="video" style="width: 100%; height: 100%; display: flex; justify-content: center;">
</div>
</div>
<script id="vimeo" async src="https://player.vimeo.com/api/player.js"></script>
<script>
function webViewBridge() {
const sendEvent = (evt, data = null) => {
// Passes events through the bridge
var payload = {
name: evt,
data: data
};
window.ReactNativeWebView.postMessage(JSON.stringify(payload));
}
var options = { id: '${VIDEO_ID}' }
const player = new Vimeo.Player('video', options)
player.ready().then(function () {
player.on('play', function () {
sendEvent('play');
})
player.on('ended', function () {
sendEvent('finish');
})
player.on('error', function () {
sendEvent('error', "Player error");
})
sendEvent('ready');
}).catch((e) => {
sendEvent('error', e.message);
})
}
let script = document.querySelector('#vimeo');
script.addEventListener('load', function () {
webViewBridge();
});
</script>
</body>
</html>

Chromecast + Youtube embed + HTML5 video tag = bug

I have been trying to play two videos (not necessarily simultaneously) on a Chromecast app. Once of them is embedded via the Youtube API and the other is a standard HTML5 video loaded via the tag.
It turns out that the Youtube video simply won't be played back on Chromecast if I also have a standard tag in my HTML5 page. But if I remove that video tag, then the Youtube video will play back nicely.
Any advice is highly appreciated!
Only one active video stream is supported on Chromecast.
I ran into this same problem.
The key elements to solve it are, unload the cast player and don't let a video tag linger in the DOM with a SRC attribute set when you attempt to play Youtube.
As for YouTube, dont let the IFRAME that contains their video player linger in the DOM either when attempting to use the HTML5 video tag.
You'll need to tear down the previous player before attempting to trigger playback through the opposing mechanism.
Here is my sample receiver I used to troubleshoot and solve the problem. This is a working example.
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #000;
overflow: hidden;
}
</style>
</head>
<body>
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/mediaplayer/1.0.0/media_player.js"></script>
<video id="chromecast" style="width: 50%; height: 50%;"></video>
<script>
var ytCode = 'sSwLhYhYgI0'
var hlsUrl = 'http://host.com/playlist.m3u8'
</script>
<!-- Chromecast -->
<script type="text/javascript">
var castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
var messageBus = castReceiverManager.getCastMessageBus('urn:x-cast:tv.domain');
cast.receiver.logger.setLevelValue(cast.receiver.LoggerLevel.DEBUG);
cast.player.api.setLoggerLevel(cast.player.api.LoggerLevel.DEBUG);
castReceiverManager.onReady = function() {
console.info('[castReceiverManager.onReady]');
castReceiverManager.setApplicationState('Ready');
};
castReceiverManager.onSenderConnected = function(sender) {
console.info('[castReceiverManager.onSenderConnected]', sender.userAgent);
};
messageBus.onMessage = function(event) {
var message = JSON.parse(event.data);
console.info('[messageBus.onMessage]', message);
};
// Normal
castReceiverManager.start({
maxInactivity: 8,
statusText: 'Ready to play',
dialData: undefined
});
window.playDirect = function(id) {
// Tear down any YT player
$('#youtube').remove();
if(!id) id = 'chromecast';
var mediaElement = document.getElementById(id);
window.host = new cast.player.api.Host({'mediaElement':mediaElement, 'url':hlsUrl});
window.host.onError = function(errorCode) {
console.log('ERROR ' + errorCode);
};
var protocol = cast.player.api.CreateHlsStreamingProtocol(window.host);
window.CCplayer = new cast.player.api.Player(window.host);
window.CCplayer.load(protocol, 25);
setTimeout(function() {
mediaElement.play();
}, 1000);
};
</script>
<!-- Youtube -->
<script>
window.onYouTubeIframeAPIReady = function() {
console.log('Initialized Youtube');
};
var playYT = function() {
// Tear down any direct player
if(window.CCplayer) {
window.CCplayer.unload();
}
$('video').attr('src', '');
// Inject div tag that will be converted to iframe with player
$('body').append('<div id="youtube" style="width: 50%; height: 50%;"></div>');
window.YTPlayer = new YT.Player(
'youtube',
{
height: '100%',
width: '100%',
playerVars: {
'autoplay': 0,
'controls': 0,
'cc_load_policy': 0,
'fs': 0,
'iv_load_policy': 0,
'modestbranding': 0,
'rel': 0,
'showinfo': 0,
'enablejsapi': 1
},
events: {
'onReady': function() {
var params = { videoId: ytCode, startSeconds: 170 };
window.YTPlayer.cueVideoById(params);
window.YTPlayer.playVideo();
},
'onError': function(err) {
console.log('YT Error ' + err);
}
}
});
};
var iframeScript = document.createElement('script');
iframeScript.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(iframeScript, firstScriptTag);
</script>
</body>
</html>
Test:
Load up the sample receiver above, and alternate the following inside the chrome debug console:
playDirect()
or
playYT()

Redirect in iframe with ios browser freezes Phaser canvas

I use Phaser to create a game but I found an problem for using it in for example facebook. When an redirect is done within an iframe the canvas is not responding after a click.
Example:
I have a IFrame and within the iframe I redirect to the game.html. When I click in the game.html everything freezes.
Everything works fine when using a computer (any browser), windows phone or android, but with an iphone or ipad it won't work.
Below are the example files to replay the problem...
index.html:
<html>
<body>
<iframe src="click.html" height="900" width="800"/>
</body>
</html>
click.html
<!DOCTYPE html>
<html>
<body>
CLICK HERE
</body>
</html>
Game.html
<!DOCTYPE html>
<html>
<head>
<style>
body{overflow:hidden;}
#game_div {
width: 760px;
height: 1100px;
margin: auto;
}
</style>
<script type="text/javascript" src="./Game/phaser.min.js"></script>
<script type="text/javascript" src="./Game/main.js"></script>
</head>
<body>
<div id="game_div"> </div>
</body>
</html>
main.js
var game = new Phaser.Game(760, 1100, Phaser.AUTO, 'game_div');
var overlay, countdownText;
var counter = 0;
var main_state = {
preload: function() {
},
create: function () {
//game overlay
overlay = game.add.graphics(0, 0);
overlay.beginFill(0x00A54F, 0.8);
overlay.drawRect(0, 0, game.width, game.height);
countdownText = game.add.text((game.width / 2), (game.height / 2), counter, { font: "65px Arial", fill: "#ffffff", align: "center" });
countdownText.anchor.set(0.5,0.5);
},
update: function() {
countdownText.setText(counter++);
}
}
game.state.add('main', main_state);
game.state.start('main');
TNX
Found the solution, with thanks to Rich Davey.
When I add the following code it works:
game.stage.disableVisibilityChange = true;

Kinetics saving image error

Im having problems with kinetics. I have a stage with kinetics with a one image and text, but that I want is export the stage to a image like myImage.jpg no like [data:image/wIlksoks.e] that it is the callback that return dataUrl() from kinetics.
Im trying with this code:
stage.toDataURL({
width: 350,
height: 350,
mimeType: "image/jpeg",
callback: function(dataUrl) {
/*
* here you can do anything you like with the data url.
* In this tutorial we'll just open the url with the browser
* so that you can see the result as an image
*/
window.open(dataUrl);
}
});
}, false);
King Regards!
You can use stage.toDataURL to get your dataURL for the server:
stage.toDataURL({
callback:function(dataURL){
// dataURL is available for saving to your server
}
});
Note: Be sure that your image and your .html are hosted on the same domain.
Otherwise your stage.toImage will fail because of CORS security.
So be sure to check your console for CORS security errors !
Alternatively:
You can use stage.toImage to create a dataURL from your image+text.
Then you can create a temp canvas to get the dataURL.
stage.toImage({
callback:function(stageImg){
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=stageImg.width;
tempCanvas.height=stageImg.height;
tempCtx.drawImage(stageImg,0,0);
var dataURL=tempCanvas.toDataURL();
// dataURL is available for saving to your server
}
});
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/RV694/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.0.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
height:300px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var img=new Image();
img.onload=function(){
start();
}
img.crossOrigin="anonymous";
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
function start(){
var kImage = new Kinetic.Image({
x: 0,
y: 0,
width: 300,
height: 300,
image:img
});
layer.add(kImage);
var kText = new Kinetic.Text({
x:20,
y:20,
fontSize:24,
fill:"blue",
text:"Hello!"
});
layer.add(kText);
layer.draw();
}
$("#stageAsImage").click(function(){
stage.toImage({
callback:function(stageImg){
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=stageImg.width;
tempCanvas.height=stageImg.height;
tempCtx.drawImage(stageImg,0,0);
var dataURL=tempCanvas.toDataURL();
var imageElement=document.getElementById("newImage");
imageElement.src=dataURL;
}
});
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="stageAsImage">Save stage as image</button>
<div id="container"></div>
<img id="newImage">
</body>
</html>

YouTube video in a Google Map Info Window

I am trying to put a youtube video into a Google Map (v3) Info Window.
It works fine in Firefox and Internet Explorer.
It does not work in Safari and Chrome. In those browsers the positioning is off and the video doesn't move when you move the map. The video also gets chopped sometimes.
Here is the code that doe
<!doctype html>
<html>
<head>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
var map;
function initialize() {
latlng = new google.maps.LatLng(33.4222685, -111.8226402)
myOptions = {
zoom: 4,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"),myOptions)
var point = new google.maps.LatLng(33.4222685, -111.8226402);
var marker = new google.maps.Marker({
position: point,
map: map
})
google.maps.event.addListener(marker, "click", function(){
bubble = new google.maps.InfoWindow({
content: '<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/UmFjNiiVk9w?fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/UmFjNiiVk9w?fs=1" type="application/x-shockwave-flash" width="425" height="344" allowscriptaccess="always" allowfullscreen="true"></embed></object>'
})
bubble.open(map, marker);
})
}
</script>
</head>
<body onload="initialize();">
<div id="map" style="width: 984px; height: 495px"></div>
</div>
</body>
</html>
An example of it working fine for the Google Maps API version 2 is here http://www.virtualvideomap.com/
Also on http://maps.google.com You can see youtube videos inside the Info Window working in Chrome and Safari by clicking "More..." on the top right of the map, and then checking "Videos".
This is a webkit bug, but you can find a solution here: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/ccaaee32b89e3656/c87bb19e4662bd78#c87bb19e4662bd78
Got a partial solution, use the iframe embed mode sorted the problem out to me!
Hope it helps!!
<!doctype html>
<html>
<head>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script>
var map;
function initialize() {
latlng = new google.maps.LatLng(33.4222685, -111.8226402)
myOptions = {
zoom: 4,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"),myOptions)
var point = new google.maps.LatLng(33.4222685, -111.8226402);
var marker = new google.maps.Marker({
position: point,
map: map
})
google.maps.event.addListener(marker, "click", function(){
bubble = new google.maps.InfoWindow({
content: '<iframe title="YouTube video player" class="youtube-player" type="text/html" width="480" height="390" src="http://www.youtube.com/embed/UmFjNiiVk9w?rel=0" frameborder="0"></iframe>'
})
bubble.open(map, marker);
})
}
</script>
</head>
<body onload="initialize();">
<div id="map" style="width: 984px; height: 495px"></div>
</div>
</body>
</html>
I recently solved this problem by adding the style:
iframe { -webkit-transform:translate3d(0,0,0); }
to my css file. In my case all of the dynamic content was already inside an iFrame and I was still having this problem. I saw this transform suggestion somewhere awhile ago, but only just tried it today. I tested it in Chrome and Safari on Windows 7. There is still some position lag, but it basically works fine now.

Resources