How to prefetch files for Howler playback? - html5-audio

This might not be a Howler issue but rather related to how HTML5 handles files for embedded playback.
Anyway, when doing a prefetching of audio files, these cached audio aren't available as soon as the network gets disconnected; and as a result, when I try to play them by invoking Howler, it won't work.
On the other hand, if I invoke Howler first and let it do the caching, then the cached files are still available for playback even when offline.
Why is that?
I use <link rel="prefetch" href="path_to_file" />, which seems to be working as the files appear on the Network Monitor activity.

Related

HTML 5 <video src="path/to/file.mp4" ...> video file is loading very slowly, sometimes never

<video id="mash-video-player"
src="videos/xyz.mp4"
width="100%"
height="100%"
controls
preload="metadata">
</video>
When the selected video is "clicked", the above HTML is dynamically built and injected into a "video player" and played back. The contents of the are replaced every time a different video is clicked.
There are many videos in the folder that get listed for playback. The first one clicked (not the first one in the list), usually gets displayed and played almost instantly. From there on, it's a roll of the dice. Click on the next one and it might take 15 seconds. Might not ever be able to be played. Even if the same exact video file is clicked.
The original video files are around 100-300MB. I processed them down to 40-80MB. The video file size doesn't matter. The slow behavior is exactly the same.
One strange side-effect of this is that when it comes to refreshing the page to restart the webapp, the reload can take just as long or sometimes never get reloaded until I reboot the web server.
There are several stacko questions out there that have similar problems. I have reviewed and tried sensible solutions.
Encoding might be a problem, but these are MP4 video files, not very big.
% file xyz.mp4
xyz.mp4: ISO Media, MP4 v2 [ISO 14496-14]
Some of the solutions talk about the metadata being at the end of the file. So there is qtfaststart, now defunct and replaced by qtfaststart2. This python app attempts to move the metadata to an optimal location. Apparently all my videos are "optimal". This is not a solution.
Other solutions talk about caching and such. But even though 300MB might take some time to shove through a python HTTP server, it shouldn't take more than a few seconds. Ultimately that might be the core of the problem: using a python HTTP server.
As a work-around, I am running the video in a profoundly old-fashioned window.open() context, but it works as expected: videos load fast and clean using a "file:///videos/xyz.mp4" URL.
Hardware/Software:
Hardware: MacPro 3.7GHz Xeon, 32GB ram
Browser: Brave Version 1.46.134
Server: Python 3.9.2, HTTPServer, SimpleHTTPRequestHandler
Client and server are both running on the same machine.
Any and all suggestions welcome.

Basic architecture to serve, stream and consume large audio files to minimize client-side resource consumption and latency

I am trying to build a web application which will need to have audio streaming functionality implemented in some way. Just to give you guys some context: It is designed to be a purely auditive experience/game/idkhowtocallit with lots of different sound assets varying in length and thus file size. The sound assets to be provided will consist of ambient sounds, spoken bits of conversation, but also long music sets (up to a couple of hours). Why I think I won't be able to just host these audio files on some server or CDN and serve them from there is, because the sound assets will need to be fetched and played dynamically (depending on user interaction) and as instantly as possible.
Most importantly, consuming larger files (like the music sets and long ambient loops) as a whole doesn't seem to be client-friendly at all to me (used data consumption on mobile networks and client-side memory usage).
Also, without any buffering or streaming mechanism, the client won't be able to start playing these files before they are downloaded completely, right? Which would add the issue of high latencies.
I've tried to do some online research on how to properly implement a good infrastructure to stream bigger audio files to clients on the server side and found HLS and MPEG-DASH. I have some experience with consuming HLS players with web players and if I understand it correctly, I would use some sort of one-time transformation process (on or after file upload) to split up the files into chunks and create the playlist and then just serve these files via HTTP. From what I understand the process should be more or less the same for MPEG-DASH. My issue with these two techniques is that I couldn't really find any documentation on how to implement JavaScript/TypeScript clients (particularly using the Web Audio API) without reinventing the wheel. My best guess would be to use something like hls.js and bind the HLS streams to freshly created audio elements and use these elements to create AudioSources in my Web Audio Graph. How far off am I? I'm trying to get at least an idea of a best practice.
To sum up what I would really appreciate to get some clarity about:
Would HLS or MPEG-DASH really be the way to go or am I missing a more basic chunked file streaming mechanism with good libraries?
How - theoretically - would I go about limiting the amount of chunks downloaded in advance on the client side to save client-side resources, which is one of my biggest concerns?
I was looking into hosting services as well, but figured that most of them are specialized in hosting podcasts (fewer but very large files). Has anyone an opinion about whether I could use these services to host and stream possibly 1000s of files with sizes ranging from very small to rather large?
Thank you so much in advance to everyone who will be bothered with helping me out. Really appreciate it.
Why I think I won't be able to just host these audio files on some server or CDN and serve them from there is, because the sound assets will need to be fetched and played dynamically (depending on user interaction) and as instantly as possible.
Your long running ambient sounds can stream, using a normal HTMLAudioElement. When you play them, there may be a little lag time before they start since they have to begin streaming, but note that the browser will generally prefetch the metadata and maybe even the beginning of the media data.
For short sounds where latency is critical (like one-shot user interaction sound effects), load those into buffers with the Web Audio API for playback. You won't be able to stream them, but they'll play as instantly as you can get.
Most importantly, consuming larger files (like the music sets and long ambient loops) as a whole doesn't seem to be client-friendly at all to me (used data consumption on mobile networks and client-side memory usage).
If you want to play the audio, you naturally have to download that audio. You can't play something you haven't loaded in some way. If you use an audio element, you won't be downloading much more than what is being played. And, that downloading is mostly going to occur on-demand.
Also, without any buffering or streaming mechanism, the client won't be able to start playing these files before they are downloaded completely, right? Which would add the issue of high latencies.
If you use an audio element, the browser takes care of all the buffering and what not for you. You don't have to worry about it.
I've tried to do some online research on how to properly implement a good infrastructure to stream bigger audio files to clients on the server side and found HLS and MPEG-DASH.
If you're only streaming a single bitrate (which for audio is usually fine) and you're not streaming live content, then there's no point to HLS or DASH here.
Would HLS or MPEG-DASH really be the way to go or am I missing a more basic chunked file streaming mechanism with good libraries?
The browser will make ranged HTTP requests to get the data it needs out of the regular static media file. You don't need to do anything special to stream it. Just make sure your server is configured to handle ranged requests... most any should be able to do this right out of the box.
How - theoretically - would I go about limiting the amount of chunks downloaded in advance on the client side to save client-side resources, which is one of my biggest concerns?
The browser does this for you if you use an audio element. Additionally, data saving settings and the detected connectivity speed may impact whether or not the browser pre-fetches. The point is, you don't have to worry about this. You'll only be using what you need.
Just make sure you're compressing your media as efficiently as you can for the required audio quality. Use a good codec like Opus or AAC.
I was looking into hosting services as well, but figured that most of them are specialized in hosting podcasts (fewer but very large files). Has anyone an opinion about whether I could use these services to host and stream possibly 1000s of files with sizes ranging from very small to rather large?
Most any regular HTTP CDN will work just fine.
One final note for you... beware of iOS and Safari. Thanks to Apple's restrictive policies, all browsers under iOS are effectively Safari. Safari is incapable of playing more than one audio element at a time. If you use the Web Audio API you have more flexibility, but the Web Audio API has no real provision for streaming. You can use a media element source node, but this breaks lock screen metadata and outright doesn't work on some older versions of iOS. TL;DR; Safari is all but useless for audio on the web, and Apple's business practices have broken any alternatives.

Some browsers are caching an icecast stream instead of playing it

I'm running three Icecast servers, all streaming the same content. Since about two weeks, I got some users reporting that they cannot listen to the stream anymore. Their browser is trying to load the stream but it never starts playing. I started to dig into this a bit and I am able to reproduce the issue.
It's interesting that this issue does not occur on all devices. I got two PCs here, both on Windows 10, both running on the latest Firefox. One can stream without any issues, one starts downloading audio data but never plays it. Opening the Icecast mountpoint in VLC works in all cases and the stream starts within a second or so. On a device that is not playing the stream in Firefox, it neither works in Chrome. On the other hand, devices that are able to stream in Firefox also are in Chrome. I guess it has something to do with the OS..?
I started Wireshark on one PC that is affected by the issue and was able to see that the browser starts to download the audio data from the Icecast server but instead of playing it, it's caching it. I believe that the browser somehow "thinks" this is a download, not a stream. When I restart the Icecast process on the server during this caching period, the caching of the browser stops and it starts to play - but only for a few seconds, until the end of the cached stream is reached.
I assume that some browsers are waiting for some kind of EOF instead of just playing the stream. Of course, an EOF is never sent in a live stream.
Here is the link to the mountpoint of one of the Icecast servers: http://185.80.187.35/live
It seems that it doesn't matter which one of the three Icecast servers you use. If one works, the other two also work. If one doesn't, opening the stream from the other servers fail as well.
I have no idea what's happening there. Since the issue occurred, nothing in the setup has been changed. I tried to switch the audio format from MP3 to OGG, but this didn't fix the issue - so I switched back to MP3. I'm currently streaming at 64 kbps. I don't think this might be an issue since this worked for years, but might it be that such a low bitrate is not supported by some browsers any more? Should I raise the bitrate? Maybe add some HTTP headers to the Icecast config? I'm confused and running out of ideas.
PS: I just noticed that I got the same issue in Edge and IE. It really seems to depend on the PC, not the browser.
When the embedded player doesn't work on a device, the stream on its' own tab doesn't play either.
This is not the behavior I'm seeing.
The site is HTTPS, yes, but the stream isn't.
Due to new security restrictions, this is no longer valid. If you open your browser's developer tools, you'll see errors about it.
You need to enable HTTPS on your Icecast server, or downgrade your site to HTTP if you want to play from non-secure origins.

Bootstrap CDN Rendering Delay

Have been working on a site and have used Boostrap via MAX CDN by putting
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
in the head section.
Google Pagespeed is showing:
Your page has 1 blocking CSS resources. This causes a delay in rendering your page.
None of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of those resources directly in the HTML.
Optimize CSS Delivery of the following:
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
Is there anyway of fixing this?
Thanks
The other answer is too incorrect, so I am writing this if anyone still needs help on this.
CDNs speed up your production websites too, not only your local development environment. Hosting a static file locally on your own host does not solve the Render Blocking issue that pagespeed tool suggests here. A static file hosted locally is still render blocking.
The solution here is inlining the render blocking CSS files completely. However, I would recommend to not inline the resources for several reasons:
Resources delivered over CDN are delivered faster. If you inline them, the entire payload is expected to deliver at slow pace.
Resources delivered separately are cached by browser, while if you inline CSS resources browser will not be able to reuse them across requests.
Resources inlined are compressed on every request along with the other dynamic contents of the file. You cannot take advantage of pre-compression that comes with CDN.
Bigger HTML document due to inlined CSS files is expected to slow when it comes to parsing.
What should one do to resolve this issue? You might think differently, but I would suggest you to do nothing.
Its not that bad if the browser has to wait a little for resources to download. If you are using CDN, chances are visitors will not perceive the download as most of the CDNs now a days have less than 50ms average global latency.
Resources are cached by browser. While pagespeed tool loads fresh resources on every request, please note that browser may be loading some of the resources from cache, completely eliminating the CDN request.
Resources are shared across websites. If you are using Bootstrap from a public CDN, chances are that the same bootstrap file is already available in browser cache of the visitor, that is downloaded when the user visited another website that used bootstrap. This gives 0ms latency and 100% bandwidth saving for that particular resource for even your first time visitors that have no other resources of your site in their browser cache. Browser can now spend the saved bandwidth elsewhere to speed other things up.
Manually inlining external libraries make it little more difficult to keep traces of all inlined copies of the library and makes the edits and updates hard.
Dynamic inlining adds few more disk seeks per request. This just adds to the server load. These IOs can be saved if the files are served separately. Your OS may just cache the files if they are hot enough. Using CDN will completely eliminate this load.
Although not exactly a solution that will remove this pagespeed warning, its possible to reduce the impact of render blocking resources for real visitors (not performance measurement tools):
Serve resources with aggressive compression to reduce the payload size.
Serve resources with immutable cache-control header to tell the browser to confidently store this file for longer period as this is not going to change in the future. If you use bootstrap cdn by pagecdn, these two optimizations are enabled by default.
If you know a file is going to be loaded immediately after a page load, you can use HTTP/2 Server Push to deliver the file before even the browser asks for it. However, if you do this, you will need to make sure that the same files are not aggressively been pushed on every request (that is not a good option as the files should load from browser cache on second request onwards).
Either change the CDN (which will most likely do nothing for you) or, simply store the file locally. This will up your Google Page Speed rate.
Download a copy of the bootstrap file you are using and store it like so root/css/bootstrap.min.css
Where root is your project folder.
CDN's are used mainly for test purposes (instant access to files) or in larger-scale projects which have multiple requirements that can't always be met locally.
Read this thread to better understand.
While the error that Google gives you might not be a serious issue for your project, it is always a good practice to use your resources locally, so that your website may load by itself, without referencing external sources that resemble in a separate query.
Static files = better load times = happy Google.

HTML5 Video playing LAN

I use HTML5 <video> tag to play videos in my LAN from different computers. In my current setup, I have got a server, which provides the html page and all the videos I want to play. There are some computers which should play these videos by loading the html page. In general that works already. But sometimes after a while playing a video, the console says failed to load resource and the playing stops immediately. I thougt, this is maybe some sort of timeout in my LAN and I had the idea to play the videos locally, i.e. copy all videos to each computer and just provide the html on the server. The server html then, just links to file://.../.
but when I tried this approach on the server, the video was stopping every few seconds and it did not buffer at all. It was completely impossible to watch the video.
Videos are *.mp4; I run chrome on all win7 computers, Server is XAMPP.
Is there either a way to catch the failed to load resource error, or a way to play local videos in a reasonable quality?
Did none of you have problems like that yet?
A few thoughts:
does your config include 'AddType video/mp4 .mp4'?
is it possible that progressive loading has been disabled somehow?
how large are the videos? there are reports of > 30Mb files having playback issues in XAMPP
if you convert to another format ( .ogg, .avi, similar ) do they playback any better?
if you use a .php (or similar) file to provide progressive loading - any change? IE Stream from the app instead of directly.