Loading remote audio files (.wav) slower much slower on ios than on android when using this flutter package - just-audio

Has anyone else found this? I'm using AudioSource.uri to get the remote audio source, then just using await player.play(); to play the remote audio file, on Android these audio files buffer and start playing a lot faster than on iOS where it takes up to 10 seconds to load and start playing (versus just 2-3 seconds on Android)

This happens because by default, iOS tries to prevent the player from having to stutter during playback when the network is slow. In effect, it waits longer for more data to be downloaded up front before allowing the audio to start.
How to override the iOS default: The AudioPlayer constructor in just_audio takes a parameter called audioLoadConfiguration where you can pass in platform specific parameters that control loading behaviour. One parameter that is relevant here is automaticallyWaitsToMinimizeStalling which you'll want to set to false. e.g.:
final player = AudioPlayer(
audioLoadConfiguration: AudioLoadConfiguration(
darwinLoadControl: DarwinLoadControl(
automaticallyWaitsToMinimizeStalling: false)));

Related

React-native-video extremely slow and possible workaround

What am I doing?
A react-native-video component is loaded into the screen with a source uri from my nodejs backend.
What is the problem? (Only tried on android)
My backend is working fine and the video is loaded, but extremely slow. I checked on the backend that the video component is requesting a byte-range of 1MB every ~1s. On the other hand, if I request the video ranges with axios, it takes a couple of ms to request multiple byte-ranges.
When using a video stored locally on the android device, the loading time is almost instantaneous.
I tried the default android player as well as exoplayer with no difference in loading times.
I am trying all this with only one Video component and when I comment it the app runs smoothly
Possible solution:
I don't want to load the data directly from the Video component and I am trying now to download the byte-ranges and store them locally. Later I plan to load these byte-ranges into the Video component.
import AsyncStorage from '#react-native-async-storage/async-storage';
...
await AsyncStorage.setItem(video_name, JSON.stringify(byte_range_data_from_backend))
This works fine and I can read the byte_range_data_from_backend later with:
const data_from_item = await AsyncStorage.getItem(video_name)
What is my question?
How can I get these video_ranges uris to pass them to the Video component?
I think I need to create some kind of file and update the file content every time I receive a new byte-range. Meanwhile, I would like the video to be played using the already downloaded byte-ranges.
Is this possible or is not a good approach? What would be a possible way to load videos fast? It would be nice to download some byte-ranges before even trying to play the video, so that the waiting time for the user is minimal.

HLS Player: Clear video.js buffer on click

I have two live videos feeding an encoder which creates H.264 chunk files and an HLS manifest which is being served by an apache web server.
A browser page using video.js shows a player. Pressing "play" on the browser properly plays the video. It works well.
However, if we change video sources (by flipping the switch in the picture below), there is a considerable delay (10 seconds) before the new content is displayed in the player. I'd like to get that to 3 seconds.
It appears that video.js and/or the HTML5 player in browser is buffering that amount of content. (if you delete the files on the web server, kill apache, or even pull the ethernet cable, the video keeps on playing!)
A button on the web page controls the switch. When clicked, I would also like to clear or reset the player so that it immediately re-reads the index.m3u8 manifest and downloads the new chunks.
So far, haven't found anything promising searching the internet or in the video.js API docs. There are lots of articles on API calls for fetching the current buffer percentage but cannot find any API for clearing it altogether.
Any ideas?
The encoder is set for 3 second chunks and the playlist depth is set for 10 entries.
I had a similar problem. Since i could not find a reliable API for this, i came up with a rather dirty workaround to clear the buffer:
var ctime = player.currentTime();
player.currentTime(0);
player.currentTime(ctime);
This currently works for me in all major browsers.

Main content starts playing before preroll in video.js when using videojs-contrib-ads

When using videojs-contrib-ads to create an ad plugin in video.js, the main programme often starts playing before the ads start playing. It seems that video.js connects to the CDN of the main content initially and then contrib-ads checks if it needs to play prerolls. A few seconds of the main content is sometimes played before this happens and only then does it start to play the adverts.
This was seen mostly on iOS on live feeds.
Does anyone know why it works like this and is there a way to stop it?
Use the prerollTimeout setting.
The maximum amount of time to wait for an ad implementation to initiate a postroll, in milliseconds. If contentended has been fired and the ad implementation does not call startLinearAdMode() before postrollTimeout expires, the content video will end playback.

Force PreloadJS to use XHR for all loading

I'm using PreloadJS as part of an application that's being built with the CreateJS libraries. PreloadJS is being used to pull in graphics and audio files listed in a manifest. I've setup a progress bar and hooked the preloader's fileprogress and fileload events to update it. I'm getting progress updates as the images load, so I can see the progress bar crawling along, but I never get fileprogress updates for the audio files, just the fileload (file is completely loaded) so the progress bar sits idle and then suddenly jumps to 100%. Since the audio files are by far the largest assets, this creates something of a problem as far as providing meaningful load progress to the user.
I've looked at the documentation for PreloadJS and it indicates that XHR loading is the preferred method because it does provide the progress updates, but that PreloadJS can fall back on things like tag-based (<audio>) loading of audio files.
None of the file loading is local or cross domain, so it would seem to me that PreloadJS ought to be using XHR.
Is there a way to force PreloadJS to use XHR for everything so I can get consistent progress updates or why would I not be getting progress events for these much larger files?
I believe there are open bugs in PreloadJS and SoundJS which prevent audio loading from reporting progress. I have logged issues for both libraries:
https://github.com/CreateJS/PreloadJS/issues/99
https://github.com/CreateJS/SoundJS/issues/119
Some additional info:
Although PreloadJS will try and favor XHR-based loading for filetypes it controls, audio loading works a little differently.
SoundJS actually injects the functionality into PreloadJS to handle loading, and will not respect the useXHR parameter, instead relying on the browser capabilities (and SoundJS plugins) to load and play audio. Unfortunately, web audio requires an array buffer (loaded with XHR), whereas HTML audio requires HTML tags, so the playback capabilities dictate how audio files load.
By default, SoundJS will default to load/use the following plugins in order:
WebAudio (therefore XHR)
HTML (therefore tag-loading)
This should favor XHR-loading and webaudio for most browsers (IE is the standout that will almost always require HTML loading). You can force plugin order by registering the plugins manually before you begin playback/
Thanks for the surfacing this!
#Lanny is correct, there are open bugs for this issue. Currently SoundJS is setup in a way that always uses Tag loading with PreloadJS, even when using WebAudio which loads via xhr. The result is that regardless of plugin, there is currently no way to get progress events.
The good news is that we are currently in the process of revising how loading works between PreloadJS and SoundJS and this issue should be resolved.

Loop wav file seamleassly in the background on windows 8

I have managed to get seamsless looping of wav files using the SharpDX library.
But this does not seem to work while the app is minimised (in the background).
Using the metro players I do not get a seamless loop this is why I use XAudio2 in the SharpDX library.
Hope someone can help with this.
When your app is in the background it no longer has access to the CPU so your audio will stop playing.
The only way around this is with background agents running the audio component. The issue here is that the certification process will be hard on you if you are just playing looping audio. Playing audio in the background is intended for audio player apps (like the inbuilt "Music" app).
If I were a user of your app I would likely be unhappy that it clogs up the audio system when it isn't in the foreground (if, for example, I went to answer a Lync call). If the only way to stop your app playing audio is to go and turn it off manually or exit the app then my opinion is that the user experience isn't great.
Of course, you may have a different opinion, or your app might be doing something I haven't considered.