I have this code
var englishSubtitle = new chrome.cast.media.Track(2,chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'english.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.CAPTIONS;
englishSubtitle.name = 'English';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;
var tracks = englishSubtitle;
var mediaInfo = new chrome.cast.media.MediaInfo(app.streamState_.manifest);
mediaInfo.contentType = app.streamState_.type;
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.tracks = tracks;
mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
var activeTrackIds = [2];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.autoplay = true;
request.currentTime = 0;
request.activeTrackIds = activeTrackIds;
session.loadMedia(request,onMediaDiscovered.bind( this, 'loadedMedia'), onMediaError);
I want to show subtitle on chromecast. When I want to set activeTracks on the request, I receive an error
Object {code: "session_error", description: "INVALID_PARAMS", details: Object}
The subtitle it doesn't show and the video doesn't play it at all, because of that error.
Am I doing something wrong?
tracks should be an array when you set
mediaInfo.tracks = tracks;
In your case, you should try
var tracks = [englishSubtitle];
and as was said earlier, use SUBTITLES instead of CAPTIONS. Finally make sure you have CORS headers present from your web server even if you are using mp4.
tracks should be stored inside an array
https://developers.google.com/cast/docs/reference/chrome/chrome.cast.media.MediaInfo#tracks
Array of non-null chrome.cast.media.Track
Array of Track objects.
mediaInfo.tracks = [englishSubtitle, frenchSubtitle, germanSubtitle]
I've created a simple javascript wrapper for the chromecast SDK:
https://github.com/Fenny/ChromecastJS
Might be worth to check out if you stumble upon more problems, good luck!
Related
Project:
Loading screen with Base64 image in Playcanvas (WebGL)
What I try to do:
Change the image when the Website is loaded with other language (index.html?language=xy)
What I already have:
I get the default image in my WebGL loading javascript.
var logo = document.createElement('img');
logo.src = 'here is my base64 code';
splash.appendChild(logo);
logo.onload = function() {
splash.style.display = 'block';
};
I thought it would be the best option to list all languages in an object, and invoke the object with the language that is currently selected.
Why I can't figure it out myself:
As I just started creating javascript projects, I need to lookup many thing, but when I search up my issue I get stuff like this Base64 encode a javascript object
Define all the images in an object
const images = {
'us': 'data:image/jpeg;base64,...',
'nl': 'data:image/jpeg;base64,...',
'fallback': 'data:image/jpeg;base64,...'
}
Parse the query paramters, use a fallback if not given
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
let lanuageKey = params['language'];
if (!images[lanuageKey]) {
lanuageKey = 'fallback';
}
Add the image with desired base64
var logo = document.createElement('img');
logo.src = images[lanuageKey];
document.body.appendChild(logo);
Putting this all together, will give something like the following snippet:
Note 1: Stack Snippets can't read the query params, so you'll need to try this locally
Note 2: Due to the 30k max chars, I had to remove the base64's
const images = {
'us': 'data:image/jpeg;base64...',
'nl': 'data:image/jpeg;base64...',
'fallback': 'data:image/jpeg;base64...'
}
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
let lanuageKey = params['language'];
if (!images[lanuageKey]) {
lanuageKey = 'fallback';
}
var logo = document.createElement('img');
logo.src = images[lanuageKey];
document.body.appendChild(logo);
So watch a tutorial on internet i created a Google App Script(GAS) for getting History id. using previous history ids i created a script which gives message id and thread id for every incoming requests and posts it on my API in function postReq(). Now when i try to use these ids in python gmail api they show error that they dont exist. I tried to get ids for certain messages and found out they are different from those given from GAS. Is this something api does or i can fix this anyway? Thanks
function doPost(e) {
let message = JSON.parse(e.postData.getDataAsString()).message
let data = Utilities.newBlob(Utilities.base64Decode(message.data)).getDataAsString();
let sheet = SpreadsheetApp.openById('...')
let doc = DocumentApp.openById('...').getBody()
let para = doc.getParagraphs()[0]
let prevId = sheet.getDataRange().getValues()[0][0];
data = JSON.parse(data)
let historyId = parseInt(data.historyId)
let history = Gmail.Users.History.list("nyxgodxd#gmail.com",{"startHistoryId": `${prevId}` }).history
let threadId = history[0].messages[0].threadId
let msgId = history[0].messages[0].id
let msg = Gmail.Users.Messages.get(userId = 'me', id = `${msgId}`).snippet
let res = {historyId,threadId, msgId,msg}
para.appendText(`\n${JSON.stringify(res)}\n`)
postReq(res)
sheet.getDataRange().setValues([[`${historyId}`]])
return 200;
}
Im using RTCMultiConnection v3 plugin i can't figure it out how to get current stream reopened.
Scenario;
UserA opens cam, appends the stream automaticly to $("#webcam"). Stream is open.
UserA wants to join UserB and does connection.join("UserB") (pretending UserB has also a cam stream). Now this html() to $("#webcam") so UserA ``$("#webcam")` is overrided by UserB stream but UserA stream is a live. So far so good.
Now i want to reappend UserA stream as UserA does connection.join("UserA") his own stream.
I hope someone knows how to do this ?
I don't want to reopen the whole stream.
The person who opens a room, must NOT join same room.
You can access the videos (media-streams) using following methods:
1) if you know the "video-id" commonly named as "stream-id"
var streamEvent = connection.streamEvents['stream-id'];
var mediaStreamObject = streamEvent.stream;
var videoFreshURL = URL.createObjectURL(mediaStreamObject);
yourVideo.src = videoFreshURL;
2) if you know th remote user's Unique-ID commonly named as "userid"
var userPeer = connection.peers['user-id'].peer;
var allIncomingVideos = userPeer.getRemoteStreams();
var firstIncomingVideo = allIncomingVideos[0];
var firstVideoFreshURL = URL.createObjectURL(firstIncomingVideo);
yourVideo.src = firstVideoFreshURL;
3) store event video in your own object
window.yourOwnGlobalObject = {};
connection.onstream = function(event) {
window.yourOwnGlobalObject[event.userid] = event;
document.body.appendChild( event.mediaElement );
};
function getUserXYZVideo(userid) {
var userVideo = window.yourOwnGlobalObject[userid].mediaElement;
// var userStream = window.yourOwnGlobalObject[userid].stream;
return userVideo;
}
How to draw analyzer from audio url?
I am getting the audio url (http://api.server.com/uploads/files/ecae64b511b1266fa3930731ec379d2dcdcc7546.wav) from an API server. I want to draw this sound on canvas, following function works on the blob object (recorded from suer), but it does not work with the url:
$window.AudioContext = $window.AudioContext || $window.webkitAudioContext;
vm.audioContext = new AudioContext();
function gotStream(stream) {
vm.inputPoint = vm.audioContext.createGain();
vm.realAudioInput = vm.audioContext.createMediaStreamSource(stream);
vm.audioInput = vm.realAudioInput;
vm.audioInput.connect(vm.inputPoint);
// audioInput = convertToMono( input );
vm.analyserNode = vm.audioContext.createAnalyser();
vm.analyserNode.fftSize = 2048;
vm.inputPoint.connect(vm.analyserNode);
vm.audioRecorder = new Recorder(vm.inputPoint);
var zeroGain = vm.audioContext.createGain();
zeroGain.gain.value = 0.0;
vm.inputPoint.connect(zeroGain);
zeroGain.connect(vm.audioContext.destination);
updateAnalysers();
}
This is probably a CORS issue if the file is from a different origin from the code. If you don't fix this, MediaStreamSource will probably just output zeroes.
I'm using localStorage in my Firefox add-on in this way:
var ioService = Components.classes['#mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
var scriptSecManager = Components.classes['#mozilla.org/scriptsecuritymanager;1'].getService(Components.interfaces.nsIScriptSecurityManager);
var domStorageManager = Components.classes['#mozilla.org/dom/storagemanager;1'].getService(Components.interfaces.nsIDOMStorageManager);
var uri = ioService.newURI('http://example.com/addon/', null, null);
var principal = scriptSecManager.getNoAppCodebasePrincipal ? scriptSecManager.getNoAppCodebasePrincipal(uri) : scriptSecManager.getCodebasePrincipal(uri);
var localStorage = domStorageManager.getLocalStorageForPrincipal(principal, '');
All works fine, but when user removes "offline data" storage is cleared. How can i workround it?
Use the preferences service to store the data in the user's profile.
var prefService = Cc["#mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService),
prefs = prefService.getBranch("extensions.YOUREXTENSIONABBREVIATIONHERE.");
var stringValue = "My Name",
booleanValue = true,
numberValue = 55;
prefs.setCharPref("stringParam", stringValue);
prefs.setBoolPref("booleanParam", booleanValue);
prefs.setCharPref("numberParam", ''+numberValue);
prefService.savePrefFile(null); // only to force an immediate save
stringValue = prefs.getCharPref("stringParam");
booleanValue = prefs.getBoolPref("booleanParam");
numberValue = parseInt(prefs.getCharPref("numberParam"), 10);
Put a defaults.js file in your defaults/preferences folder and initialize preferences for a new user. You'll get an error if you try to retrieve a preference that doesn't exist and there's no way to check if it exists.
Look here:
https://developer.mozilla.org/en-US/docs/Adding_preferences_to_an_extension