I want to play a sound when the user click on a image. I'm using SoudManager plugin.
Here you can check what I'm doing:
soundManager.setup({
url: 'swf',
onready: function() {
soundCarro = soundManager.createSound({
id: 'soundCarro',
url: 'sound/carro_camona.mp3'
});
soundMoto = soundManager.createSound({
id: 'soundMoto',
url: 'sound/moto_camona.mp3'
});
soundNautico = soundManager.createSound({
id: 'soundNautico',
url: 'sound/nautico_camona.mp3'
});
}
});
As you can see, I create 3 sound objects (soundCarro, soundMoto and soundNautico).
Here the action, where when the user clicks on it, the scrollTo function is called:
<img id="ca" class="ca logo" onclick="scrollTo('secao-carros',true);" src="images/svg/CAhome.svg">
Here you can see the scrollTo function:
function scrollTo(target,sound){
if(sound){
var delay = 0;
if(target == 'secao-carros'){
soundCarro.play();
delay = 700;
duration = 750;
}
if(target == 'secao-motos'){
soundMoto.play();
delay = 900;
duration = 750;
}
if(target == 'secao-nauticos'){
soundNautico.play();
delay = 850;
duration = 2000;
}
$('html, body').delay(delay).animate({ scrollTop: $('#'+target).offset().top }, {duration: duration});
}else{
$('html, body').animate({ scrollTop: $('#'+target).offset().top }, {duration: 750});
}
}
As you can see, in this function I execute the sound object created (ex: soundNautico.play();).
The issue is that on iPad and Android devices this sound gets a big delay to execute, but in desktop browsers it works perfect!
How can I prevent this delay?
That's because desktop browsers will preload the audio so when you call .play() the browser will begin playing it immediately because it has already buffered some (if not all) of the audio.
I know that iOS and most other mobile browsers will A) only allow you to play a single audio file at a time, B) not allow you to cache audio at all, and C) only allow you initialize/play an audio object if the user physically initiated the action on the same call stack. So you're basically out of luck if you don't want the delay.
Edit: You could add an event listener to the audio and only trigger the scroll after the audio had buffered. However, you cannot load more than one sound at a time.
audio.addEventListener("canplay", function(e) {
doScroll();
audio.play();
}, false);
```
Related
I am developing a radio app using ionic creator.
audio play function works ok, but I need to pause to audio
Another question:
Double clicking to listen to two tunes at once?
this is audio play function,
function ($scope, $stateParams) {
$scope.playWebAudio = function(){
try{
$scope.audio = new Audio('Audio stream URL');
$scope.audio.play();
}
catch(e){
alert(e);
console.log(e);
}
}
play button
ng-click playWebAudio()
Strop Audio you have to use $cordovaMedia plugin instead of $cordovaNativeAudio
now you have to do like this:
module.controller('MyCtrl', function($scope, $cordovaMedia) {
var src = "/src/audio.mp3";
var media = $cordovaMedia.newMedia(src);
var iOSPlayOptions = {
numberOfLoops: 2,
playAudioWhenScreenIsLocked : false
}
media.play(iOSPlayOptions); // iOS only!
media.play(); // Android
media.pause();
media.stop();
media.release();
media.seekTo(5000); // milliseconds value
media.setVolume(0.5);
media.startRecord();
media.stopRecord();
media.getDuration();
media.getCurrentPosition().then(...);
});
for more detail refer to this tlink enter link description here
I am using jquery to load YouTube Video through iframe to reduce the initial page load time. Using this approach – only the video thumbnail is loaded along with the page and the actual player loads when the user hits the play button. But AutoPlay is not working on Android and Iphones though it is perfectly working on desktops using windows. When I googled this problem, it turns out "Chrome and Safari browsers on iPhone and Android only allow playback of HTML5 video when initiated by a user interaction. They block embedded media from automatic playback to prevent unsolicited downloads over cellular networks." I want to autoplay the video. Please help.
Here is my jquery
document.addEventListener("DOMContentLoaded",
function() {
var div, n,
v = document.getElementsByClassName("youtube-player");
for (n = 0; n < v.length; n++) {
div = document.createElement("div");
div.setAttribute("data-id", v[n].dataset.id);
div.innerHTML = YouTubeThumb(v[n].dataset.id);
div.onclick = YouTubeIframe;
v[n].appendChild(div);
}
});
function YouTubeThumb(id) {
var thumb = '<img src="https://i.ytimg.com/vi/ID/mqdefault.jpg">',
play = '<div class="play"></div>';
return thumb.replace("ID", id) + play;
}
function YouTubeIframe() {
var iframe = document.createElement("iframe");
var embed = "https://www.youtube.com/embed/ID?autoplay=1";
iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
iframe.setAttribute("frameborder", "0");
iframe.setAttribute("allowfullscreen", "1");
this.parentNode.replaceChild(iframe, this);
}
and the HTML
<div class="youtube-player" data-id="YouTube_Video_ID"></div>
try this example:-
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
I have an android application that sends the camera stream through a webview through peerjs (webrtc) the web application on the browser receives the video and streams it.
Things are working but the video on the web is too slow and the image freezes for some time before getting the second image...
Is there a way to make the resolution lower ? or buffer the video on the web application ? or can it be something wrong with my implementation ?
Android Webview code:
initVideo = function(videoSourceValue) {
var video = document.querySelector('video');
navigator.getUserMedia({video: {optional: [{
sourceId: videoSourceValue
}]
}
},function(stream) {
video.src = window.URL.createObjectURL(stream);
$('#peerId').text("calling : " + SERVER_PEER_ID);
var mediaConnection = peer.call(SERVER_PEER_ID, stream);
mediaConnection.on('stream', function(remoteStream) {
// Show stream in some video/canvas element.
});
},function(e){
console.log('failed',e);
});
}
Web part:
function getVideoStream() {
PEER.on('call', function(call) {
var mediaConnection = navigator.getUserMedia({video: true}, function(stream) {
call.answer(stream); // Answer the call with an A/V stream.
call.on('stream', onReceiveStream);
}, function(err) {
console.log('Failed to get local stream' ,err);
});
});
}
function onReceiveStream(stream){
console.log('received stream');
$('video').prop('src',window.URL.createObjectURL(stream));
}
Thanks
Update 1
I tried to add {reliable : true}, still having the same issue.
I'm also sending location data to the server, and it seems that the video streams and location data are sent together periodically (the chart on the web showing speed and the video move at the same time) but the frame rate is too slow.
When you establish the video/audio stream you can specify some constraints...
var videoOptions = (isCordova) ? {audio: true, video: true} :
{ audio: true,
video: {
mandatory: {
maxWidth: 640,
maxHeight: 360,
// maxAspectRatio:4/3,
// maxFrameRate:1
},
quality: 7,
width: { ideal: 320 },
height: { ideal: 240 }
}
};
navigator.getUserMedia(videoOptions, function (stream) {
In the above code, if you are on a device (android/ios) you don't get to choose, but you can control it on the browser. A quality of 5 is the level that the video driver author deemed as an acceptable trade off between quality and bandwidth. Limiting the dimensions of the picture helps too.
See this link for mode details: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
My issue was completely unrelated to bandwidth, I simply didn't put autoplay on the video tag , so the video was only refreshing when a redraw was happening.
Thanks a lot for your answers they really give insight on how things work in webrtc.
How does Media.release() work. Looking at the docs it feels that you have to use it like this:
MediaService.loadMedia('sounds/connection-error.wav').then(function(media){
media.play();
media.release();
});
But I googled enough to know that is wrong. We have to explicitly release the core instances on Android.
But how to do that? If I have 8 views in my app and if I play a sound file on each of those views does that count as 8 core instances being used? And can I go back to say view number 1 and again play the sound associated with that view? If so, would that count as a 9th instances ?
Straight away calling media.release() just like above does not play any sound at all.
Most common way to play sounds using Cordova Media plugin is following:
function playAudio(src) {
// HTML5 Audio
if (typeof Audio != "undefined") {
new Audio(src).play() ;
// Phonegap media
} else if (typeof device != "undefined") {
// Android needs the search path explicitly specified
if (device.platform == 'Android') {
src = '/android_asset/www/' + src;
}
var mediaRes = new Media(src,
function onSuccess() {
// release the media resource once finished playing
mediaRes.release();
},
function onError(e){
console.log("error playing sound: " + JSON.stringify(e));
});
mediaRes.play();
} else {
console.log("no sound API to play: " + src);
}
}
I am creating an application in which user has to record video not more that 15 seconds. How to check duration while capturing video in phonegap. User should not record video more than 15 seconds.
I dont want to use the below code.
navigator.device.capture.captureVideo(function(mediaFiles) {
mediaFiles[0].getFormatData(function(data) {
if(data.duration > 15) {
alert('Your video is longer than the allowed 30 seconds.');
}
});
}, function(error) { alert('An error occured'); }, null);
This checks duration after capturing video.
Is it possible to stop recording video once user reach limit of 15 second.
In cordova have many option to handle this.....
so you need set
navigator.device.capture.captureVideo(captureVideoSuccess, captureErrorVideo, {
destinationType: destinationType.FILE_URL,duration:15});
duration take in seconds....When camera reached 15 seconds of video its automatically closed and call captureVideoSuccess. now you write your logic here..........
Check this
This has been posted long time ago, but I'll answer this anyway since I had similiar problem (but with audio). What you could do on Android is to set timeout with function that will stop recording.
Here's my code for audio recording with timeout after 10 seconds:
var src = "tmprecording.amr";
mediaRec = new Media(src, function() { // success
console.log("recordAudio():Audio Success");
}, function(err) { //error
console.log("recordAudio():Audio Error: "+ err.code);
});
//Record audio
mediaRec.startRecord();
timeout = setTimeout(function(){
//Here's your recording stop
mediaRec.stopRecord();
mediaRec.release();
mediaRec = null;
}, 10000);
Does that help?