It seems that new YT.Player() is working in development but not production.
var player = new YT.Player(domId, {
events: {
onReady: function() {
// because of a bug in the youtube iframe api
var p;
player.addEventListener('onStateChange', function(e) {
if (e.data === 1) {
p = $interval(function() {
var elapsedTime = Math.floor(player.getCurrentTime());
$scope.skim.sections[len-1].startTime = elapsedTime;
setHMS($scope.skim.sections[len-1], elapsedTime);
}, 1000);
}
else {
$interval.cancel(p);
}
});
console.log("onReady fired");
updateStartTimeAndSeekTo($scope.skim.sections[len-1]);
player.pauseVideo();
}
}
});
This code is supposed to update some input fields when the video plays. It does this in development, but not production.
This is the live page. This is a video explaining how it is supposed to work. And this is the relevant GitHub code.
I really don't know how to debug this.
For some reason the console.log() statements don't seem to be appearing in production. Without those I don't know what to do.
I checked the network tab and it seems that the api code is being downloaded successfully.
And heroku logs shows no errors.
<iframe style="height: 156.443444006753px;" src="https://www.youtube.com/embed/3eMA0GvpXl0?showinfo=0&enablejsapi=1&origin=http://localhost:9000" ng-class="{ 'unloadedFrame': !skim.videoUrl }" class="subsection-iframe" responsive-height="" resize-on-load="" allowfullscreen="" frameborder="0" ng-src="skim.embedUrl" id="subsection-0-0"></iframe>
Check the iframe source url contain origin=http://localhost:9000 hardcoded. If you removed the origin parameter from url. It started working.
The problem could be in the production environment config file. Adding
config.assets.debug = true to production.rb fixed it for me.
Related
I have this problem where in firefox the speech gets cut off if the page is auto-refreshed, but in google chrome it finishes saying the speech even if the page is auto-refreshed. How do I fix it so that the speech doesn't get cut off in firefox even when the page is auto-refreshed?
msg = new SpeechSynthesisUtterance("please finish saying this entire sentence.");
window.speechSynthesis.speak(msg);
(function ($) {
'use strict';
if (window == window.top) {
var body = $('body').empty();
var myframe = $('<iframe>')
.attr({ src: location.href })
.css({ height: '95vh', width: '100%' })
.appendTo(body)
.on('load', function () {
var interval;
interval = 750;
setTimeout(function () {
myframe.attr({ src: location.href });
}, interval);
});
}
})(jQuery);
I have this problem where in firefox the speech gets cut off if the
page is auto-refreshed, but in google chrome it finishes saying the
speech even if the page is auto-refreshed.
The described behaviour for Firefox is a sane expected implementation.
Browsing the source code of Firefox and Chromium the implementation of speechSynthesis.speak() is based on a socket connection with the local speech server. That server at *nix is usually speech-dispatcher or speechd (speech-dispatcher). See How to programmatically send a unix socket command to a system server autospawned by browser or convert JavaScript to C++ souce code for Chromium? for description of trying to implement SSML parsing at Chromium.
Eventually decided to write own code to achieve that requirement using JavaScript according to the W3C specification SpeechSynthesisSSMLParser after asking more than one question at SE sites, filing issues and bugs and posting on W3C mailings lists without any evidence that SSML parsing would ever be included as part of the Web Speech API.
Once that connection is initiated a queue is created for calls to .speak(). Even when the connection is closed Task Manager might still show the active process registered by the service.
The process at Chromium/Chrome is not without bugs, the closest that have filed to what is being described at the question is
Issue 797624: "speak speak slash" is audio output of .speak() following two calls to .speak(), .pause() and .resume()
Why hasn't Issue 88072 and Issue 795371 been answered? Are Internals>SpeechSynthesis and Blink>Speech dead? (for possible reason why "but in google chrome it finishes saying the speech even if the page is auto-refreshed." is still possible at Chrome)
.volume property issues
Issue 797512: Setting SpeechSynthesisUtterance.volume does not change volume of audio output of speechSynthesis.speak() (Chromium/Chrome)
Bug 1426978 Setting SpeechSynthesisUtterance.volume does not change volume of audio output of speechSynthesis.speak() (Firefox)
The most egregious issue being Chromium/Chrome webkitSpeechReconition implementation which records the users' audio and posts that audio data to a remote service, where a transcript is returned to the browser - without explicitly notifying the user that is taking place, marked WONT FIX
Issue 816095: Does webkitSpeechRecognition send recorded audio to a remote web service by default?
Relevant W3C Speech API issues at GitHub
The UA should be able to disallow speak() from autoplaying #27
Precisely define when speak() should fail due to autoplay rules #35 (ironically, relevant to the reported behaviour at Chromium/Chrome and output described at this question, see Web Audio, Autoplay Policy and Games and Autoplay Policy Changes)
Intent to Deprecate: speechSynthesis.speak without user activation
Summary
The SpeechSynthesis API is actively being abused on the web. We don’t have hard data on abuse, but since other autoplay avenues are
starting to be closed, abuse is anecdotally moving to the Web Speech
API, which doesn't follow autoplay rules.
After deprecation, the plan is to cause speechSynthesis.speak to
immediately fire an error if specific autoplay rules are not
satisfied. This will align it with other audio APIs in Chrome.
Timing of SpeechSynthesis state changes not defined #39
Timing of SpeechSynthesisUtterance events firing not defined #40
Clarify what happens if two windows try to speak #47
In summary, would not describe the behaviour at Firefox as a "problem", but the behaviour at Chrome as being a potential "problem".
Diving in to W3C Web Speech API implementation at browsers is not a trivial task. For several reasons. Including the apparent focus, or available option of, commercial TTS/SST services and proprietary, closed-source implementations of speech synthesis and speech recognition in "smart phones"; in lieu of fixing the various issues with the actual deployment of the W3C Web Speech API at modern browsers.
The maintainers of speechd (speech-dispatcher) are very helpful with regards to the server side (local speech-dispatcher socket).
Cannot speak for Firefox maintainers. Would estimate it is unlikely that if a bug is filed relevant to the feature request of continuing execution of audio output by .speak() from reloaded window is consistent with recent autoplay policies implemented by browsers. Though you can still file a Firefox bug to ask if audio output (from any API or interface) is expected to continue during reload of the current window; and if there are any preferences or policies which can be set to override the described behaviour, as suggested at the answer by #zip. And get the answer from the implementers themselves.
There are individuals and groups that compose FOSS code which are active in the domain and willing to help SST/TTS development, many of which are active at GitHub, which is another option to ask questions about how to implement what you are trying to achieve specifically at Firefox browser.
Outside of asking implementers for the feature request, you can read the source code and try create one or more workarounds. Alternatives include using meSpeak.js, though that still does not necessarily address if Firefox is intentionally blocking audio output during reload of the window.
Not sure why there's a difference in behavior... guest271314 might be on to something in his answer. However, you may be able to prevent FF from stopping the tts by intercepting the reload event with a onbeforeunload handler and waiting for the utterance to finish:
msg = new SpeechSynthesisUtterance("say something");
window.speechSynthesis.speak(msg);
window.onbeforeunload = function(e) {
if(window.speechSynthesis.speaking){
event.preventDefault();
msg.addEventListener('end', function(event) {
//logic to continue unload here
});
}
};
EDITED: See more elegant solution with promises below initial answer!
Below snippet is a workaround to the browser inconsistencies found in Firefox, checking synth.speaking in the interval and only triggering a reload if it's false prevents the synth from cutting of prematurely:
(It does not NOT work properly in the SO snippet, I assume it doesn't like iFrames in iFrames or whatever, just copy paste the code in a file and open it with Firefox!)
<p>I'm in the body, but will be in an iFrame</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var synth = window.speechSynthesis;
msg = new SpeechSynthesisUtterance("please finish saying this entire sentence.");
synth.speak(msg);
(function ($) {
'use strict';
if (window == window.top) {
var body = $('body').empty();
var myframe = $('<iframe>')
.attr({ src: location.href })
.css({ height: '95vh', width: '100%' })
.appendTo(body)
.on('load', function () {
var interval;
interval = setInterval(function () {
if (!synth.speaking) {
myframe.attr({ src: location.href });
clearInterval(interval);
}
}, 750);
});
}
})(jQuery);
</script>
A more elaborate solution could be to not have any setTimeout() or setInterval() at all, but use promises instead. Like this the page will simply reload whenever the message is done synthesizing, no matter how short or long it is. This will also prevent the "double"/overlapping-speech on the initial pageload. Not sure if this helps in your scenario, but here you go:
<button id="toggleSpeech">Stop Speaking!</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
if (window == window.top) {
window.speech = {
say: function(msg) {
return new Promise(function(resolve, reject) {
if (!SpeechSynthesisUtterance) {
reject('Web Speech API is not supported');
}
var utterance = new SpeechSynthesisUtterance(msg);
utterance.addEventListener('end', function() {
resolve();
});
utterance.addEventListener('error', function(event) {
reject('An error has occurred while speaking: ' + event.error);
});
window.speechSynthesis.speak(utterance);
});
},
speak: true,
};
}
(function($) {
'use strict';
if (window == window.top) {
var body = $('body').empty();
var myframe = $('<iframe>')
.attr({ src: location.href })
.css({ height: '95vh', width: '100%' })
.appendTo(body)
.on('load', function () {
var $iframe = $(this).contents();
$iframe.find('#toggleSpeech').on('click', function(e) {
console.log('speaking will stop when the last sentence is done...');
window.speech.speak = !window.speech.speak;
});
window.speech.say('please finish saying this entire sentence.')
.then(function() {
if ( window.speech.speak ) {
console.log('speaking done, reloading iframe!');
myframe.attr({ src: location.href });
}
});
});
}
})(jQuery);
</script>
NOTE: Chrome (since v70) does NOT allow the immediate calling of window.speechSynthesis.speak(new SpeechSynthesisUtterance(msg)) anymore, you will get an error speechSynthesis.speak() without user activation is no longer allowed..., more details here. So technically the user would have to activate the script in Chrome to make it work!
Firefox:
First of all type and search for the “about: config” inside the browser by filling it in the address bar. This will take to another page where there will be a pop up asking to Take Any Risk, you need to accept that. Look for the preference named “accessibility.blockautorefresh” from the list and then right-click over that. There will be some options appearing as the list on the screen, select the Toggle option and then set it to True rather than False. This change will block the Auto Refresh on the Firefox browser. Remember that this option is revertable!
I am trying to control the debugger using Chrome Extension.
I am using devtools-protocol and chrome extension documentation, but I have no idea how to implement them as I have not seen any samples of the methods in use. I used the sample extension from here which shows how to pause and resume the debugger only, but that's absolutely no use to me. I tried to implement some methods in the sample, but nothing happens.
function onDebuggerEnabled(debuggeeId) {
chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
lineNumber: 45825,
url: 'full https link to the js file from source tab'
});
}
The problem is that the js file I am trying to debug is loaded from the website inside the sources tab and it's huge, we talking 150k+ lines after its been formatted and it takes some time to load.
Now can anyone tell me how to simply add a break point inside the js file from the sources (USING CHROME EXTENSION) so it could be triggered on action which will then stops the debugger so I could change values etc?
Maybe you are placing wrong breakpoint location (formatted source), try working with original source and add columnNumber: integer
and here working version JavaScript pause/resume -> background.js:
install this extension
open https://ewwink.github.io/demo/Debugger.setBreakpointByUrl.html
click debugger pause button
click button "Debug Me!"
it will hit breakpoint on https://ewwink.github.io/demo/script.js at line 10
click debugger continue button, you will see message variable "hijacked..."
the code:
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// mod by ewwink
var attachedTabs = {};
var version = "1.1";
chrome.debugger.onEvent.addListener(onEvent);
chrome.debugger.onDetach.addListener(onDetach);
chrome.browserAction.onClicked.addListener(function(tab) {
var tabId = tab.id;
var debuggeeId = {
tabId: tabId
};
if (attachedTabs[tabId] == "pausing")
return;
if (!attachedTabs[tabId])
chrome.debugger.attach(debuggeeId, version, onAttach.bind(null, debuggeeId));
else if (attachedTabs[tabId])
chrome.debugger.detach(debuggeeId, onDetach.bind(null, debuggeeId));
});
function onAttach(debuggeeId) {
if (chrome.runtime.lastError) {
alert(chrome.runtime.lastError.message);
return;
}
var tabId = debuggeeId.tabId;
chrome.browserAction.setIcon({
tabId: tabId,
path: "debuggerPausing.png"
});
chrome.browserAction.setTitle({
tabId: tabId,
title: "Pausing JavaScript"
});
attachedTabs[tabId] = "pausing";
chrome.debugger.sendCommand(
debuggeeId, "Debugger.enable", {},
onDebuggerEnabled.bind(null, debuggeeId));
}
function onDebuggerEnabled(debuggeeId) {
chrome.debugger.sendCommand(debuggeeId, "Debugger.setBreakpointByUrl", {
lineNumber: 10,
url: 'https://ewwink.github.io/demo/script.js'
});
}
function onEvent(debuggeeId, method, params) {
var tabId = debuggeeId.tabId;
if (method == "Debugger.paused") {
attachedTabs[tabId] = "paused";
var frameId = params.callFrames[0].callFrameId;
chrome.browserAction.setIcon({
tabId: tabId,
path: "debuggerContinue.png"
});
chrome.browserAction.setTitle({
tabId: tabId,
title: "Resume JavaScript"
});
chrome.debugger.sendCommand(debuggeeId, "Debugger.setVariableValue", {
scopeNumber: 0,
variableName: "changeMe",
newValue: {
value: 'hijacked by Extension'
},
callFrameId: frameId
});
}
}
function onDetach(debuggeeId) {
var tabId = debuggeeId.tabId;
delete attachedTabs[tabId];
chrome.browserAction.setIcon({
tabId: tabId,
path: "debuggerPause.png"
});
chrome.browserAction.setTitle({
tabId: tabId,
title: "Pause JavaScript"
});
}
demo
EDIT: Just saw your comment about this being for a custom extension you're writing. My answer won't help you (sorry!), but it might help people that come here looking for a way of setting normal breakpoints in Chrome.
Maybe you already did, but... Have you tried just clicking the line number of the line you want to set the breakpoint in?
Like this:
You can even enable or disable breakpoints in several different calls in the same line.
When the page is loaded, open Dev Tools with F12, then navigate to the JS file in the Sources panel, and add the breakpoints you want. Then, refresh the page to load it again -- Chrome will remember where you set the breakpoints and stop at them.
If you can modify the source code of the file that you want to debug, I would look use the debugger statement.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
function potentiallyBuggyCode() {
debugger; //application will break here as long as chrome developer tools are open
}
function breakhere() {
debugger;
}
ok, for start you have to sendCommand Debugger.enable .. something like this:
var tabId = parseInt(window.location.search.substring(1));
window.addEventListener("load", function() {
chrome.debugger.sendCommand({tabId:tabId}, "Debugger.enable");
chrome.debugger.attach( tabId, "0.1" );
chrome.debugger.onEvent.addListener(onEvent);
});
then inside you onEvent you can set breaking points
function onEvent(debuggeeId, message, params) {
if (tabId != debuggeeId.tabId) return;
var res = Debugger.setBreakpointByUrl( 2, 'url-of-the-script-file' );
}
I would strongly suggest to check the sniffing section on this page: https://chromedevtools.github.io/devtools-protocol/ because I was able to see the json that get returned via WS protocol and that will help you to do pretty much anything you want.. I can't build you full extension, you are on your own man,,
I guess that you need to add somekind of DOM elemnet with list of scripts that you'll parse from Network.getResponseBody and then somekind of UX tool to pick that scripts and let users to debugging,, that process could take you some time :(
hope I have steered you in the right direction, good luck!
The error only happens when i try to view the website(video) over the internet.
Everything works perfectly when i am running locally in visual studio and it also works perfectly when i remote desktop into the production webserver where i published the site to and browse to the site locally there.
If i had to guess it seems like something is timing out when it goes over the internet or maybe there is something on our firewall preventing the movie from streaming to me from the production webserver. I doubt the firewall is the issue because i can view other videos streamed with video.js from other sources.
My developertools console window shows this (I tried to post a screenshot but i didnt have enough rep points):
GET http://166.62.34.149/Videos/Walgreens_8700SKedzieAve.m4v net::ERR_CONNECTION_ABORTEDvideo.js:118 s.loadvideo.js:65 Tvideo.js:75 s.loadVideo.aspx?VideoName=Walgreens_8700SKedzieAve.m4v:59 (anonymous function)video.js:36 s.Hvideo.js:28 t.a.t.ua.extend.ivideo.js:6 dvideo.js:57 t.Player.t.a.extend.ivideo.js:6 dvideo.js:2 tVideo.aspx?VideoName=Walgreens_8700SKedzieAve.m4v:57 (anonymous function)
here is my code:
<script type="text/javascript">
var videoName;
//videojs.autoSetup();
videoName = document.getElementById('lblVideoName').innerHTML;
videojs('my_video_1', {}, function(){
this.src({ type: "video/mp4", src: "/Videos/" + videoName });
this.load();
this.play();
});
videojs('my_video_1').ready(function () {
// Store the video object
var myPlayer = this, id = myPlayer.id();
var aspectRatio = 478 / 850;
function resizeVideoJS() {
var width = document.getElementById(id).parentElement.offsetWidth;
myPlayer.width(width).height(width * aspectRatio);
}
resizeVideoJS();
window.onresize = resizeVideoJS;
});
function PausePlayer() {
var myPlayer = videojs('my_video_1');
myPlayer.pause();
};
</script>
I have set my IIS mime type, so that isnt the issue. Any help you have provide would be greatly appreciated.
Thanks everyone!
I know this is an old oner but just to let you know that I came across this with our website and after digging deep into mime types, changing sources, removing cache and so on, a simple options --> advanced --> "Reset" made everything work fine.
This will obviously only be the case if you can test it working on other PC's somewhere else to confirm all the mime types and video work in the first place.
Hope this is of help to someone in the future as it was the top Google result for me.
Regards
Liam
I have a web application which is intermittently producing an error when using Chrome 30.0.1599.101 m.
I am using the HTML5 <video /> tag and controlling the src attribute using javascript.
The page which is causing the error sometimes errors on the first video or on the seventh. There is no predictable pattern.
Here is the javascript which handles the src:
var playing = false;
var media = $('#video')[0];
function initModule() {
$.ajax({
url: recap,
type:'HEAD',
error:
function(){
screenNotify('Error!', false, "404: Module video content could not be found." + recap, true);
},
success:
function() {
media.src = recap;
registerListeners(media);
media.load();
}
});
}
function registerListeners(listen) {
listen.addEventListener('ended', hide_recap);
listen.addEventListener('error', mediaError);
}
function mediaError(event) {
screenNotify('Media Error!', false, "Media failed with code: " + event.currentTarget.error.code, true);
}
function play_recap() {
if (!playing) {
playing = true;
media.play();
}
}
function hide_recap() {
if (playing) {
playing = false;
media.pause();
media.currentTime = 0.0;
}
}
Interestingly, there is no error thrown when I call media.load(), instead, you need to look at the network requests to see that the GET has actually produced a result of (failed).
Another thing to note, is this GET status only occurs for videos which reside within this particular folder location: /interactive/vids/recap/. The error does not occur anywhere else within the application.
Finally, the last thing which is strange about this error, is when the application finally attempts to play the video from play_recap(), about 1 second of the video will actually play, followed by an error being thrown on the video element.
The error is MEDIA_ERR_NETWORK however this application is installed locally on a Tomcat server and is running under localhost.
So why is the GET request producing (failed) and the HTML5 <video> element producing a MEDIA_ERR_NETWORK when everything is only ever running on localhost?
I've noticed very similar issue with Chrome 31. I'm getting inconsistently MEDIA_ERR_NETWORK, all other tested browsers work fine.
I haven't found any other solution than just retrying - you could try recreate the video element or just change currentTime - it always helps in my case.
I've recently been trying to create a metro app for Windows 8 and tried to use settings flyout.
So I followed msdn quickstart: http://msdn.microsoft.com/en-us/library/windows/apps/hh780611.aspx
However, I can't make it work.
Here's the part where I add the settings flyout:
function setupSettings() {
app.onsettings = function (e) {
e.detail.applicationcommands = { 'serv_changer': { title: 'Change Server', href: 'settings.html' } };
WinJS.UI.SettingsFlyout.populateSettings(e);
}
}
The function setupSettings is called only once when I press a button (so I can make sure it only gets executed once)
Here's my issue: after pressing the button, the "Change Server" link does appear. However, when I click on it, nothing happens and the side window just fades out.
Here are the things I tried so I know it's not one of these:
It is not the file missing. I tried to put a different file that didn't exist and an exception was thrown and the program crashed. Here, it does not crash.
The HTML is properly coded, as I tried to replace settings.html by one of Microsoft's example settings file.
I am having troubles figuring out why it does not work.
Could somebody help (I can provide more code if needed) ?
Thank you.
In your settings.html page, make sure the data-win-control declaration includes setting the name of the commandId - this seems to be missing from the online example.
Eg.
If your js file declares the command as:
e.detail.applicationcommands = { 'serv_changer': { title: 'Change Server', href: 'settings.html' } };
...then make sure your settings.html file references 'serv_changer':
<div data-win-control="WinJS.UI.SettingsFlyout" data-win-options="{settingsCommandId:'serv_changer', width:'wide'}">
on my app, I have slash slash in my href. so something like this href: '/settings.html'
Also on your settings.html page make sure you have this data-win-control="WinJS.UI.SettingsFlyout"
Replace your js function
function setupSettings() {
app.onsettings = function (e) {
e.detail.applicationcommands = { 'serv_changer': { title: 'Change Server', href: 'settings.html' } };
WinJS.UI.SettingsFlyout.populateSettings(e);
}
}
with this:
function setupSettings(e) {
e.detail.applicationcommands =
{
"serv_changer":
{
title: "Change Server",
href: "/settings.html"
}
};
WinJS.UI.SettingsFlyout.populateSettings(e);
}
and also make sure serv_changer is referenced in your settings.html file:
<div data-win-control="WinJS.UI.SettingsFlyout" data-win-options="{settingsCommandId:'serv_changer'}">