cefsharp cannot play audio by javascript - javascript

I am writing a dictionary program using CefSharp by C#. When the dictionary page(i.e.[Longman-love][1]) is loaded I want it could play its pronounce automatically(by clicking the pronouce icon using JavaScript). Here are related codes:
C# part:
browser.FrameLoadEnd += (sender, args) =>
{
//Wait for the MainFrame to finish loading
if (args.Frame.IsMain)
{
browser.ExecuteScriptAsync("document.getElementsByClassName('amefile')[0].click();");
}
};
JavaScript part(I copyed it from web and added some 'alert's for debugging the program):
$(document).ready(function(){
var audio = null;
$(".speaker").click(function(){
alert('x');
var src_mp3 = $(this).attr("data-src-mp3");
if (supportAudioHtml5())
playHtml5(src_mp3);
else if (supportAudioFlash())
playFlash(src_mp3);
else
playRaw(src_mp3);
});
function supportAudioHtml5(){
var audioTag = document.createElement('audio');
try {
return ( !!(audioTag.canPlayType)
&& (audioTag.canPlayType("audio/mpeg") != "no" && audioTag.canPlayType("audio/mpeg") != "" ) );
} catch(e){
return false;
}
}
function supportAudioFlash() {
var flashinstalled = 0;
var flashversion = 0;
if (navigator.plugins && navigator.plugins.length){
x = navigator.plugins["Shockwave Flash"];
if (x){
flashinstalled = 2;
if (x.description) {
y = x.description;
flashversion = y.charAt(y.indexOf('.')-1);
}
} else {
flashinstalled = 1;
}
if (navigator.plugins["Shockwave Flash 2.0"]){
flashinstalled = 2;
flashversion = 2;
}
} else if (navigator.mimeTypes && navigator.mimeTypes.length){
x = navigator.mimeTypes['application/x-shockwave-flash'];
if (x && x.enabledPlugin)
flashinstalled = 2;
else
flashinstalled = 1;
} else {
for(var i=7; i>0; i--){
flashVersion = 0;
try{
var flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i);
flashVersion = i;
return (flashVersion > 0);
} catch(e){}
}
}
return (flashinstalled > 0);
}
function playHtml5(src_mp3) {
alert('html5');
if(audio != null){
if(!audio.ended){
audio.pause();
if(audio.currentTime > 0) audio.currentTime = 0;
}
}
//use appropriate source
audio = new Audio("");
if (audio.canPlayType("audio/mpeg") != "no" && audio.canPlayType("audio/mpeg") != "")
audio = new Audio(src_mp3);
//play
audio.addEventListener("error", function(e){alert("Apologies, the sound is not available.");});
alert('will play');
audio.play();
}
The last alert sentence alert('will play'); showed but I could not hear anything. However,when I clicked the audio icon directly in the CefSharp browser, it could play the pronounce. How could I fix this problem? I am not a native English speaker, I hope you can understand me. Many thanks!
[1]: https://www.ldoceonline.com/dictionary/love

This problem occured beacause Google had changed autoplay policy for audios and videos. You can active auto play by adding a commandline flag --autoplay-policy=no-user-gesture-required. In my case:
public BrowserForm()
{
InitializeComponent();
var settings = new CefSettings();
settings.CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache");
settings.CefCommandLineArgs.Add("enable-media-stream", "1");
settings.CefCommandLineArgs["autoplay-policy"] = "no-user-gesture-required";//Add this statement solve the problem
Cef.Initialize(settings);
//some other statements
}
If anyone happens to meet the same problem in the futrue, I hope this will help you!
Here is a related topic.

Related

How to register/unregister events in a dynamic way, using Vanilla JS

I've spoken to my teacher and he told me that the reason why you would place the <script> element as last part of <body>, use onload= event directly on HTML-element, or in another way include the script in <body> (or deferring its execution), is because you want to guarantee that the script will only be activated once the DOM has been loaded, and the needed elements can be accessed. But... this is not the convention since it will be very difficult to scale in a solution where multiple HTML-documents are involved, sharing the same file resources such as JavaScript in this case. Instead, you'll handle this flow of execution by registering events properly using JS.
I've been told to put the Window Event load at the end my of JS file.
These are the error I get in booking.html: Uncaught TypeError: Cannot read property 'target' of undefined at addEvent (main.js:65) at start (main.js:10) addEvent.
Why do I get this error?
Here is my code:
function start() {
let path = window.location.pathname;
if (path.endsWith("contact.html")) {
browserDetection;
} else if (path.endsWith("employees.html") || path.endsWith("ourfleet.html")) {
registerGalleryEvents();
} else if (path.endsWith("booking.html")) {
addEvent();
getSeat();
}
/* browser detector */
var browserDetection = (function (agent) {
switch (true) {
case agent.indexOf("edge") > -1:
return "MS Edge (EdgeHtml)";
case agent.indexOf("edg") > -1:
return "Microsoft Edge";
case agent.indexOf("opr") > -1 && !!window.opr:
return "Opera";
case agent.indexOf("chrome") > -1 && !!window.chrome:
return "Chrome";
case agent.indexOf("trident") > -1:
return "Internet Explorer";
case agent.indexOf("firefox") > -1:
return "Mozilla Firefox";
case agent.indexOf("safari") > -1:
return "Safari";
default:
return "other";
}
})(window.navigator.userAgent.toLowerCase());
document.getElementById("specific-h3").innerHTML = "Here you can contact us if you have any questions. <br>\ <br>\ And by the way, you are using " + browserDetection + " browser.";
function registerGalleryEvents() {
const galleryImgs = document.querySelectorAll(".galleryImg");
galleryImgs.forEach((galleryImg) => {
galleryImg.addEventListener("click", () => {
displayImage(galleryImg);
});
});
}
//declaring the displayImage function. reference: https://stackoverflow.com/a/65974064/14502646
function displayImage(thumbnail) {
const currentImgSrc = thumbnail.getAttribute("src");
const [imgName, ext] = currentImgSrc.split(".");
document.getElementById('myPicture').src = imgName + '-big.' + ext;
}
var seats = document.getElementsByClassName('grid-item')
// Saving Javascript objects in sessionsStorage.
var data = JSON.parse(sessionStorage.getItem('bookingData'))
function addEvent(event) {
//Makes sure that the first 6 seats are Business class and the rest are Economy.
if (parseInt(event.target.innerHTML) >= 1 && parseInt(event.target.innerHTML) <= 6) {
document.getElementById('classType').innerHTML = 'Class Type: Business'
} else {
document.getElementById('classType').innerHTML = 'Class Type: Economy'
}
//event.target.innerHTML is the number of seat that is selected.
document.getElementById('seat').innerHTML = 'Seat Selected: ' + event.target.innerHTML
document.getElementById('seatNumber').value = event.target.innerHTML
var selectedSeats = document.getElementsByClassName("selected");
if (selectedSeats.length > 0) {
for (var j = 0; j < selectedSeats.length; j++) {
selectedSeats.item(j).className = selectedSeats.item(j).className.replace('grid-item selected', 'grid-item');
}
}
event.target.className = event.target.className + " selected";
}
for (var i = 0; i < seats.length; i++) {
seats[i].addEventListener('click', addEvent)
}
var seatList = document.getElementsByClassName("grid-item")
for (var i = 0; i < data.length; i++) {
seatList.item(parseInt(data[i].seatNo) - 1).removeEventListener("click", addEvent)
seatList.item(parseInt(data[i].seatNo) - 1).className = seatList.item(parseInt(data[i].seatNo) - 1).className.replace('grid-item', 'grid-item booked')
}
document.getElementsByClassName('reset').addEventListener('click', function () {
location.reload()
})
function getSeat() {
var inp = document.getElementsByClassName("grid-item selected");
if (inp.length > 0) {
var inputData = {
firstName: document.getElementById('fname').value,
lastName: document.getElementById('lname').value,
identityNo: document.getElementById('identity').value,
classType: document.getElementById('classType').innerHTML,
seatNo: parseInt(document.getElementById('seatNumber').value)
}
if (JSON.parse(sessionStorage.getItem('bookingData')) != null) {
var bookingData = JSON.parse(sessionStorage.getItem('bookingData'))
bookingData.push(inputData)
sessionStorage.setItem('bookingData', JSON.stringify(bookingData))
} else {
console.log('block')
var bookingData = []
bookingData.push(inputData)
sessionStorage.setItem('bookingData', JSON.stringify(bookingData))
}
alert('Flight booked successfully.')
window.print()
} else {
alert("Select a seat before proceeding!")
}
}
}
window.addEventListener("load", start);

isMatch() function not working correctly in JavaScript

I am trying to use an empty array which fills when clicking on an image send the Image ID to a findMatch() function which in turn is used to insert the a match in a isMatch() function. My isMatch() function is not working correctly. I have tried debugging in Chrome but this is not helping. Any help or advice would be appreciated. I need to clear the array after 2 images are selected.
function isMatch() {
if ((count === 1) && (pic == 1)) {
cMatch.unshift(arrMatch);
match1 = imgID;
}
if ((count === 2) && (pic == 1)) {
// var index2=deClick(clicked);
cMatch.push(arrMatch);
match2 = imgID; {
if (cMatch[0] === cMatch[1]) {
bMatch = true;
cMatch.length = 0;
cMatch = [];
count = 0;
match1 = 0;
match2 = 0;
} else {
bMatch = false;
document.getElementById(match1).src = defaultImage;
document.getElementById(match2).src = defaultImage;
cMatch.length = 0;
cMatch = [];
count = 0;
match1 = 0;
match2 = 0;
}
//else{bMatch=false;}}
}
if (count > 2) {
document.getElementById(match1).src = defaultImage;
document.getElementById(match2).src = defaultImage;
count = 0;
return bMatch;
}
}
}
The code when stepping in Chrome seems to work but when I use in the browser it does not work at all.

Animate CC HTML5 - toggle fullscreen

I have this code (below) on a buton to force my HTML5 game to fullscreen, but I'd like to have it turn back also with the button - right now it only works using ESC key. Is it possbile?
this.fsbtn.addEventListener("click", doFullscreen);
function doFullscreen() {
var i;
var elem = document.getElementById("animation_container");
var fs = ["requestFullscreen", "webkitRequestFullscreen", "mozRequestFullScreen", "msRequestFullscreen"];
for (i = 0; i < 4; i++) {
if (elem[fs[i]]) {
elem[fs[i]]();
break;
}
}
}
Sure it's possible. Change your doFullscreen function to a toggle one that checks if it's fullscreen or not:
function toggleFullscreen(event) {
var element = document.body;
if (event instanceof HTMLElement) {
element = event;
}
var isFullscreen = document.webkitIsFullScreen || document.mozFullScreen || false;
element.requestFullScreen = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || function () {
return false;
};
document.cancelFullScreen = document.cancelFullScreen || document.webkitCancelFullScreen || document.mozCancelFullScreen || function () {
return false;
};
isFullscreen ? document.cancelFullScreen() : element.requestFullScreen();
}
Read the documentation here for fullscreen API
You can exit from fullscreen mode using functions listed below(for more read documentation)
In JS/HTML code you can add button with absolute position and high z-index. Write new click listener for added button and run cancelFullscreen function, that's all.
Example JS function for FullScreen mode:
function toggleFullScreen() {
if (!document.mozFullScreen && !document.webkitFullScreen) {
if (videoElement.mozRequestFullScreen) {
videoElement.mozRequestFullScreen();
} else {
videoElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
if (document.mozCancelFullScreen) {
videoElement.mozCancelFullScreen();
} else {
videoElement.webkitCancelFullScreen();
}
}
}
Working example you can see here: https://developer.mozilla.org/samples/domref/fullscreen.html

Edit ajax loaded content

I have a HTML that loads a table from another page. I've got the CSS to work properly, but I can't edit the table using jQuery when it's pooled by the script, only when I have the table directly on the page. I'm guessing that maybe my changes are running before the load? I don't know..
I want to let you know that I'm not a programmer my self, but more of a curious person. I've searched around and found some things, but the lack of knowledge doesn't let me implement them. Hope you can help me.
The Script I use to read the data from the other page (p1.html)
<script type="text/javascript">
var TimerLoad, TimerChange;
var MaxNum, Rafraichir, Changement, ClassementReduit, ClassementReduitXpremier;
var UrlRefresh, UrlChange;
Rafraichir = 30000;
Changement = 150000;
MaxNum = 1;
ClassementReduit = 0;
ClassementReduitXpremier = 10;
function Load(url, target) {
var xhr;
var fct;
if (UrlChange) url = UrlRefresh;
else UrlRefresh = url;
UrlChange = 0;
if (TimerLoad) clearTimeout(TimerLoad);
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP")
} catch (e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP")
} catch (e2) {
try {
xhr = new XMLHttpRequest
} catch (e3) {
xhr = false
}
}
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200)
if (ClassementReduit == 0) document.getElementById(target).innerHTML = xhr.responseText;
else document.getElementById(target).innerHTML = ExtraireClassementReduit(xhr.responseText)
};
xhr.open("GET", url + "?r=" + Math.random(), true);
xhr.send(null);
fct = function() {
Load(url, target)
};
TimerLoad = setTimeout(fct, Rafraichir)
}
function ExtraireClassementReduit(Texte) {
var i, j, CompteurTD, CompteurTR;
var ColPosition, ColNumero, ColNom, ColEcart1er;
var Lignes;
var NouveauTexte;
CompteurTR = 0;
ColPosition = -1;
ColNumero = -1;
ColNom = -1;
ColEcart1er = -1;
Texte = Texte.substring(Texte.indexOf("<tr"));
Lignes = Texte.split("\r\n");
NouveauTexte = '<table width="100%" cellpadding="0" cellspacing="0">';
for (i = 0; i < Lignes.length; i++)
if (Lignes[i].substring(0, 3) == "<tr") {
NouveauTexte += Lignes[i];
CompteurTD = 0
} else if (Lignes[i].substring(0, 4) == "</tr") {
CompteurTR++;
if (CompteurTR == ClassementReduitXpremier + 1) break
} else if (Lignes[i].substring(0, 3) == "<td") {
if (CompteurTR == 0)
if (Lignes[i].indexOf("\"Id_Position\"") != -1) {
ColPosition = CompteurTD;
NouveauTexte += Lignes[i].replace(/ width=".*"/i, "")
} else if (Lignes[i].indexOf("\"Id_Numero\"") != -1) {
ColNumero = CompteurTD;
NouveauTexte += Lignes[i].replace(/ width=".*"/i, "")
} else if (Lignes[i].indexOf("\"Id_Nom\"") != -1) {
ColNom = CompteurTD;
NouveauTexte += Lignes[i].replace(/ width=".*"/i, "")
} else {
if (Lignes[i].indexOf("\"Id_Ecart1er\"") != -1) {
ColEcart1er = CompteurTD;
NouveauTexte += Lignes[i].replace(/ width=".*"/i, "")
}
} else if (CompteurTD == ColPosition || CompteurTD == ColNumero || CompteurTD == ColNom || CompteurTD == ColEcart1er) NouveauTexte += Lignes[i];
CompteurTD++
}
NouveauTexte += "</table>";
return NouveauTexte
}
function Change() {
var Num, Index;
if (document.forms["Changement"].chkChangement.checked) {
Index = UrlRefresh.indexOf(".");
Num = parseInt(UrlRefresh.substring(1, Index)) + 1;
if (Num > MaxNum) Num = 1;
UrlRefresh = "p" + Num + ".html";
UrlChange = 1;
fct = function() {
Change()
};
TimerChange = setTimeout(fct, Changement)
} else if (TimerChange) clearTimeout(TimerChange)
};
</script>
Loading the table into the body
$(document).ready(Load('p1.html', 'result'));
The code I need to run after (it works with the table directly on page or even on a button, but I can't get to work on page load)
function show_hide_column(col_id, do_show) {
var stl;
if (do_show) stl = 'block'
else stl = 'none';
var tbl = document.getElementsByTagName('table')[0];
var index = document.getElementById(col_id).cellIndex;
var rows = tbl.getElementsByTagName('tr');
for (var row = 0; row < rows.length; row++) {
var cels = rows[row].getElementsByTagName('td')
cels[index].style.display = stl;
}
}
function hide() {
show_hide_column("Id_Position", false);
show_hide_column("Id_Equipe", false);
show_hide_column("Id_Vehicule", false);
}
I fired a console.log() message for every stage of the previous code, to know when exactly the table was added to the page, to then hide the columns. Got it to work.

Input button never appears when javascript detects form completed

I'm making a register page using HTML, CSS and JS and Java servlet etc. I have a monitorer() function which checks if the user has finished inputting everything before making the register button visible. But now everything works, but somewhere am getting screwed over and the button never comes back..
my button in reg.html :
<input type="submit" value="Register" class="btnSub" id="btnReg" style="visibility:hidden;"/>
javascript function monitorer()
function monitorer() {
var btnReg = document.getElementById("btnReg");
btnReg.style.visibility = "hidden";
var flag = true;
if (document.getElementById("fname").value.length >= 3) {
if (document.getElementById("lname").value.length >= 3) {
if (valiDate(document.getElementById("dob"))) {
if (document.getElementById("USN").value.length == 10) {
if (document.getElementById("passw").value.length > 5) {
var ticks = document.getElementsByClassName("checker"), i = 0;
for (i = 0; i < ticks.length; i++) {
if (ticks.item(i).innerHTML == "✔") {
alert("i val = " + i);
continue;
} else {
flag = false;
break;
}
}
}
} else {
flag = false;
document.getElementById("USN").focus();
}
} else {
flag = false;
document.getElementById("dob").focus();
}
} else {
flag = false;
document.getElementById("lname").focus();
}
} else {
flag = false;
document.getElementById("fname").focus();
}
if (flag == true) {
btnReg.style.visibility = "visible";
} else if(flag == false) {
btnReg.style.visibility = "hidden";
}}
And to help you get as good a picture as you can, a screenshot
See - all the ticks are there, the first name, last name etc are having value.length >=3 but still the register button doesn't show..
Also, I have put the monitorer() method in every input's "onBlur", "onChange" events.
Here is a link to my html file >>> reg.html
and please let me know if i can improve anything?

Categories