Good day,
I'm currently building a website for myself (I'm a composer/producer), and I'm using Media Element for the main demo page. The page is under construction at the following link:
http://www.vincentrubinetti.com/listen.html
http://www.vincentrubinetti.com/listen.js
Below are what I think are the relevant functions and code:
function initPlayer()
{
player = new MediaElementPlayer('#listen_player',{
success: function (mediaElement, domObject)
{
mediaElement.addEventListener('play', resumeSong, false);
mediaElement.addEventListener('ended', playNextSong, false);
mediaElement.addEventListener('pause', pauseSong, false);
}
});
[omitted]
}
function setSong(element)
{
if (element != "")
{
unselectAllSongs();
document.getElementById(element).className = "listen_song_highlight";
[omitted]
var newSrc = document.querySelector("#"+element+" .listen_song_source").title;
player.pause();
player.setSrc(newSrc);
player.load();
}
}
function playSong(element)
{
document.querySelector("#"+element+" .listen_song_status").innerHTML = "playing";
player.play();
}
function playNextSong()
{
var newSong = document.querySelector(".listen_song_highlight + div.listen_song");
if (autoplay && newSong != null)
{
setSong(newSong.id);
playSong(newSong.id);
}
else
{
document.querySelector(".listen_song_highlight .listen_song_status").innerHTML = "stopped";
}
}
All the CSS end of this seems to be fine. It finds the next song on the list and sets the new source; I've verified it does this properly via alert and other debugging. However, on the Android default browser and the Dolphin browser, it seems to not be able to load the mp3 sometimes, and prematurely triggers the "ended" event to go to the next song. The result is that it appears to skip 2-3 songs after one is done playing. And it takes some finagling even to get it to play one, clicking on the song divs and the player play button. I can type in the same url that's in the html, and the browser will play/download it just fine, no problems accessing or loading it.
Here are the 3 mp3 files that repeat down the playlist, for reference. They are by me, but are placeholders for the real music.
NEW/music/creation.mp3
NEW/music/startup.mp3
NEW/music/win.mp3
Note that all of this works properly on Chrome, Firefox, IE8+, and Android Chrome (I haven't tested iPhone or iPad yet).
Is my diagnosis correct? Can anyone point me in the right direction? Is there any experience where MediaElement doesn't work properly on the Android default and Dolphin browsers?
I have the same problem in android (but with video...)
I was told that this is an issue with the file not being downloaded in time -- i.e. the browser starts the download, but since the file isn't downloaded it is 0:00 long, so the ended event is triggered.
If there is someway to make it so that the video / audio can be downloaded faster it solves the problem.
Strangely enough, if the device has good WiFi then this problem basically disappears.
See what John Dyer said about it here:
https://github.com/johndyer/mediaelement/issues/543
Related
My website plays a background song and some audio effects at the same time. Although the song loads fine (I can see its duration via Audio.duration property), it doesn't play, while the audio effects play (I have already clicked on the screen to activate audio playing). On Firefox in my PC it plays without problem. The audio file is a 10 MB mp3 (but my Android is at home wi-fi). Below is part of my code.
var music,clicked=false,downloaded=false;
function play() {
music.play();
}
function canPlay() {
downloaded = true;
if (clicked) {
play();
}
}
function touchStart(e) {
if (!clicked) {
clicked = true;
if (downloaded) {
play();
}
}
}
function load() {
music = new Audio('mp3/music.mp3');
music.addEventListener('canplaythrough',canPlay,false);
window.addEventListener('touchstart',touchStart,false);
}
The load function is called in the onload of body. The clicked and downloaded variables are required because I never know what happens first: the user click or the audio finish downloading.
On Google mobile-friendly test, it says the audio file couldn’t be loaded (Status: Other error). I've read this test doesn't wait for more than 3 seconds. However, reading the time of the song in seconds doesn't prove it has downloaded?
Why won't the song play on mobile?
EDIT
I created a timer interval that tells me the position (music.currentTime) of the song once every minute. On desktop, it gives the right time. On mobile, it always gives 0, meaning that the song, although loaded (?), isn't really being played.
EDIT 2
I investigated the promise returned by music.play(), and noticed it was giving the error: "(NotAllowedError: play() failed because the user didn't interact with the document first)". It seems that touchStart doesn't count as a "user interaction" the way that mouseDown does...
In the end, I removed both touchStart and touchEnd (each with his own preventDefault), leaving the song to be played after the resulting mouseDown. I've kept the touchMove, however, because it's different from the mouseMove, and required for my site.
I am developing a karaoke app which consist of animation and playback song. The most important thing here is very precise synchronization between both.
I implemented it few months ago and on iOS 9/10 everything was working great. We had a problem with Android app (ExoPlayer) because there were too big delay between playback and animation. Finally we found out that the problem was caused by wrong song format (mp3) - which was explained here: https://github.com/google/ExoPlayer/issues/3233. We fixed it by packing song into mp4 format (on iOS there is still mp3 used).
I use AVPlayer with HLS
self.player = AVPlayer(url: url)
//
var currentTime_: Double {
if let player = self.player {
return player.currentTime().seconds
}
return 0
}
Everything was ok until iOS 11 release. On iOS 11 there is the same desynchronization (player.currentTime is not accurate) that was on Android.
What's interesting is that even app that was build on iOS 10 SDK and is available on AppStore doesn't work properly on iOS 11 - but it still works great on iOS 10.
Nothing on server side was changed. So Apple had to change something in decoding/buffering. Right now we are working on changing audio format/decoding but still I am curious - why that has happened? Anyone encountered something similar?
Regards
You need use this option when create AVURLAsset
let asset = AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
If you not use this option, AVPlayer measures mp3 audio duration by file length, so it has small error to get duration.
As woosiki pointed it out, you need to use the AVURLAsset. Just keep in mind that loading of large files will take longer due to the pre-calculation of the precise duration. You may want to put a loader indicator.
func prepareAudioFile(with track: Track) {
guard let url = URL(string: track.streamURL) else {
return
}
let asset = AVURLAsset(url: url,
options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
let playerItem = AVPlayerItem(asset: asset)
player = AVPlayer(playerItem: playerItem)
observePlayerProgress()
}
private func observePlayerProgress() {
let interval = CMTimeMake(value: 1, timescale: 5)
player.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] time in
if let track = self?.player.currentItem, track.status == .readyToPlay {
// Once the loading is finished this callback will return
// Here you can calculate and set duration and elapsed time (track.duration, time.seconds)
}
}
}
I am building an AIR ActionScript 3.0 application. Whenever i am trying it on the pc, by doing Command + Enter and testing the movie, the app will work fine, and a collision between two movie clips is working fine. However, when i try to publish it and get the appropriate apk, the app will run normally, but no collision will take place! as if the two movie clips just fly above each other and nothing happens ! While on the PC, its working perfectly! I am new to AS3, so anyone can point out where am i going wrong? This is the code i am using for the collision :
function ifHitAct(e:Event):void
{
for each (var obstacle in runNow.manyObs)
{
//trace("the obstacle Index Created is" , parent.getChildIndex(runNow.obstacle));
//parent.setChildIndex(runNow.obstacle ,1)
if (MC1.hitTestObject(obstacle))
{
hit.play(0);
runNow.manyObs.splice(runNow.manyObs.indexOf(obstacle), 1);
//this.removeChild(obstacle);
score++;
scoreField.text = String(score);
obstacle.alpha = 0;
}
}
}
the problem was actually a little weird, but it worked! If any future users notices the same problem, you should check you Music!! well, i am calling a sound effect when i wrote " hit.play(0) " . I haven't embed any mp3 file, so whenever i try to run my app on a real device, the compiler just breaks on that line, and simply bypasses all the rest of the code. So, when i embed the mp3 file, it all worked fine! To embed the mp3 file, just use the following structure :
[Embed(source='/hit.mp3')]
private var MySound : Class;
private var sound : Sound;
and then initiate your var whenever you need the music to play :
function ifHitAct(e:Event):void
{
//
for each (var obstacle in runNow.manyObs)
{
if (MC1.hitTestObject(obstacle))
{
sound = (new MySound()) as Sound;
sound.play(0);
runNow.manyObs.splice(runNow.manyObs.indexOf(obstacle), 1);
score++;
scoreField.text = String(score);
obstacle.alpha = 0;
}
}
}
And it will all work perfectly.
I am building a phonegap app with jquery mobile and using build.phonegap.com
I have an event to change the page to the login screen after startup process have completed.
This works fine but it will not work on my andriod device unless a debugger is attached to it, in which case it works fine.
The code I have is
$.mobile.changePage("login.html");
I have put this in the mobileinit, pageshow, and now on document.ready function but it doesnt change the behaviour.
I've checked if $.mobile is a function and it is, Have tried everything and can not seem to figure out why this would be happening, any feedback would be much appreciated
I managed to put in a hack to work around this issue.
It was something to do with my phone being really old and slow, so something was getting a little messed up on old/slow andriod versions.
To prevent this from being an Issue I figured out this way that solves the issue and boots up my jquery mobile app on phone gap even if the phone is very slow.
$(document).bind('mobileinit', function () {
setTimeout(function () {
var html = $(".loading-status-text").html();
/* The html has Please Wait in the dom so we know it han't been touched by jQuery */
if (html == 'Please Wait') {
window.location.href = 'index.html';
}
}, 10000);
$(document).on("pageshow", function (e) {
var pageId = $.mobile.activePage.attr('id').toString();
if (pageId == 'loadingScreen') {
/* This wouldn't fire at first */
$(".loading-status-text").html("Welcome to Appname");
$.mobile.changePage("login.html");
}
});
});
I am creating one HTML mobile website for android & ios device.
I know click to call for both.
ANDROID
2125551212
iOs
Live Support
Now, my problem is i have one webpage with click to call link and want that link work for both android / ios
Just use tel: it will work on iOS, android, blackbarry OS, windows and many more. Using this scheme will work on almost all mobile browsers on.
You have to recognize the client. Since different phones have different user agents, you can do something like this with JavaScript:
if (navigator.userAgent.indexOf("Android") != -1) {
txt = "2125551212";
} else if (navigator.userAgent.indexOf("iPhone") != -1) {
txt = "Live Support";
}
This works for me as well.
212-555-1212
The problem with this is it will break add-ons and extensions that people may use on desktop browsers.
The plain phone number will call on click for Android OS.
<p>212-555-1212</p>
You can also track this call with AdWords. I am working on getting it to work with Google Analytics.
In regards to MoyShe's post and not to steal her code (complements) I would add a conditional default for Desktop browsers and other as well using a default else statement.
if (navigator.userAgent.indexOf("Android") != -1) {
txt = "2125551212";
} else if (navigator.userAgent.indexOf("iPhone") != -1) {
txt = "Live Support";
}
<!--what about other devices OS-->
else {
txt = "<span><strong>Phone -</strong> 282-122-9627 ext.7877</span>";
}
That way desktop browsers users could also see a phone number as it would display a phone number by default if the device is not of the two handheld device queried.
I am not versed in android, blackberry, IOs, windows, etc...but I would also like to ask or point out my comment section.
<!--what about other devices OS-->
(For Newbs- the above line of commented code can be removed when pasting in the web page).
What about blackberry and all the other device OS's? Are they Android or IOs driven OS's? If not, additional code to specifically identify those devices would also need to be created and included in the (else if's) statements.
If I am correct in my unknown question, a Switch/Case statement might be cleaner and a better way to go.
as on
Msaccess Help Australia www.msaccess.com.au
You only want ordinary text showing on a PC browsers
so put this line in your page
<script type="text/javascript" src="javascript.js"></script>
and save the below in a file called javascript.js
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf ("mobile");
if (isAndroid)
{document.write('<a class="mobilesOnly" href="tel:++61476132591"> Click here to call tel:++61476132591</a>');}
else
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPad/i)))
{document.write('<a class="mobilesOnly" href="tel:++61476132591"> Click here to call now: tel:++61476132591</a>');}
else
{document.write('Call ++61476132591') ;}
don't forget to change the number :)