javascript - HTML Audio element source from cache - Stack Overflow

I am building a web application for playing some audio files offline. I have read and tested the Cache

I am building a web application for playing some audio files offline. I have read and tested the Cache part of the Service Worker API, and I can easily add all my audio files to a named cache. However, the browser does not seem to use it when I add a <audio src='/audio/file.mp3'> to the DOM and play() it, even if that exact URL is added to a cache.

It makes sense in some way that the cache is not automatically used, as then it would not be any point in naming the cache.

I am using create-react-app, and as I have not ejected, I'm not controlling the Service Worker. As far as I understand, though, it is not remended to cache larger files up front anyway, so I'm created a function in the UI to let the user decide when to cache all files.

My question is: How can I put a cached audio file into the audio element?

EDIT: I thought the problem should be understandable from my question, but was asked to add code, so here is what I've tried.

The markup has an audio element and two buttons. First button loads an mp3 url into a cache, second button tries two different ways of setting this as a source for the audio element:

  1. Insert blob from cached response
  2. Set cached request url as audio src

None of them works, of course, that's why I write this. :)

<div>
    <audio src="/audio/shape_of_you.mp3" controls/>
</div>
<div>
    <button onclick="addToCache()">Add to cache</button>
    <button onclick="playCachedAudio()">Play cached audio</button>
</div>


<script>
    function addToCache() {
        caches.open('myCache').then((cache) => {
            cache.add('/audio/rise.mp3').then(() => {
                console.log('cached');
            });
        });
    }

    function playCachedAudio() {
        caches.open('myCache').then((cache) => {
            cache.match('/audio/rise.mp3').then((cachedAudio) => {
                cachedAudio.blob().then(cont => {
                    let audioEl = $('audio');
                    audioEl.attr('src', cont);
                    // ...fails with the following error in console:
                    // HTTP “Content-Type” of “text/html” is not supported. Load of media resource http://localhost:3000/[object%20Blob] failed.
                    // Cannot play media. No decoders for requested formats: text/html
                    audioEl.attr('src', '/audio/rise.mp3');
                    // Works online, but not offline (resource is not found)
                });
            });
        });
    }
</script>

I am looking for either

a way to add the blob as audio content

or

another way to programatically force browser to guarantee a list of audio files to be cached for offline use.

I am building a web application for playing some audio files offline. I have read and tested the Cache part of the Service Worker API, and I can easily add all my audio files to a named cache. However, the browser does not seem to use it when I add a <audio src='/audio/file.mp3'> to the DOM and play() it, even if that exact URL is added to a cache.

It makes sense in some way that the cache is not automatically used, as then it would not be any point in naming the cache.

I am using create-react-app, and as I have not ejected, I'm not controlling the Service Worker. As far as I understand, though, it is not remended to cache larger files up front anyway, so I'm created a function in the UI to let the user decide when to cache all files.

My question is: How can I put a cached audio file into the audio element?

EDIT: I thought the problem should be understandable from my question, but was asked to add code, so here is what I've tried.

The markup has an audio element and two buttons. First button loads an mp3 url into a cache, second button tries two different ways of setting this as a source for the audio element:

  1. Insert blob from cached response
  2. Set cached request url as audio src

None of them works, of course, that's why I write this. :)

<div>
    <audio src="/audio/shape_of_you.mp3" controls/>
</div>
<div>
    <button onclick="addToCache()">Add to cache</button>
    <button onclick="playCachedAudio()">Play cached audio</button>
</div>


<script>
    function addToCache() {
        caches.open('myCache').then((cache) => {
            cache.add('/audio/rise.mp3').then(() => {
                console.log('cached');
            });
        });
    }

    function playCachedAudio() {
        caches.open('myCache').then((cache) => {
            cache.match('/audio/rise.mp3').then((cachedAudio) => {
                cachedAudio.blob().then(cont => {
                    let audioEl = $('audio');
                    audioEl.attr('src', cont);
                    // ...fails with the following error in console:
                    // HTTP “Content-Type” of “text/html” is not supported. Load of media resource http://localhost:3000/[object%20Blob] failed.
                    // Cannot play media. No decoders for requested formats: text/html
                    audioEl.attr('src', '/audio/rise.mp3');
                    // Works online, but not offline (resource is not found)
                });
            });
        });
    }
</script>

I am looking for either

a way to add the blob as audio content

or

another way to programatically force browser to guarantee a list of audio files to be cached for offline use.

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jan 28, 2018 at 22:18 aweibellaweibell 4451 gold badge6 silver badges14 bronze badges 4
  • Can you include the code that you have tried at the Question? See stackoverflow./help/mcve – guest271314 Commented Jan 28, 2018 at 22:20
  • @guest271314 I did not add any code initially, as I did not see that it would make a significant difference to understanding the question, but hopefully you will be able to respond now :) – aweibell Commented Jan 31, 2018 at 10:11
  • @aweibell do you intend to serve the files as stream (response 206) or as a whole (like a download)? – Jankapunkt Commented Oct 5, 2018 at 13:00
  • @Jankapunkt My intention is to be able to download all tracks when online, and later play them in the browser. I have unfortunately been sick and unable to work with this. Hope to pick up the remaining bits soon! – aweibell Commented Oct 5, 2018 at 22:02
Add a ment  | 

1 Answer 1

Reset to default 5

There are two concepts mentioned about. The Cache API and service workers. These are often used together but not part of the same specification. You can use the Cache API without Service workers. This is exactly what you are doing in the code you provided.

Note that using the Cache API never guaranties that the files will remain forever, it is still a cache. However, browsers seems to try its best to keep files.

Now, lets look at the problem. You want to load the content from the cache if it is stored there, and I assume you want to load it from network if not. One solution is to use a service worker. The service worker works in the background, intercepting fetch events (if you configure it to). I have created a sample application (Source code) that uses this approach.

The audio-tag configured with a src-attribute like you normally do. Then I have a service worker that listens to fetch events, checks if the request is for an audio file, then returns the cached version or a network version. I added buttons to add/remove the file from cache, and a status field to see if its added. The remove button and status is not needed, but nice for demonstration.

Note that the service worker uses caches.match(request) without specifying a cache name. The cache name is only used to group cached item for easier maintenance by the developer. It makes it easier to delete / replace many resources at the same time. It's also easier to inspect the cache in dev-tools or iterate over its items.

I can not answer how to add the service worker to your specific application. Consult the documentation for create-react-app.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744796931a4594260.html

相关推荐

  • javascript - HTML Audio element source from cache - Stack Overflow

    I am building a web application for playing some audio files offline. I have read and tested the Cache

    2天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信