HTML-аудиоэлемент отключен, хотя src верен

У меня есть аудио-элемент HTML, в котором src указывает на действительный URL-адрес, но аудио-элемент выделен серым цветом и отключен. Рядом с элементом audio у меня есть ссылка, ведущая непосредственно на URL-адрес src, который правильно указывает на mp3-файл на S3.

Не могу понять, почему аудиоплеер отключен. Это реализовано в коде Svelte ниже. Происходит в браузерах Chrome и Safari.

Как я могу удалить отключенное состояние этого аудиоплеера?

<script>
    import { onMount } from 'svelte';
    import { slide } from 'svelte/transition';
    import { BACKEND_URL } from '$lib/constants';
    import { isRtlLanguage } from '$lib/utils';
    import Ping from '$lib/components/loading/Ping.svelte';

    export let text = 'hello';
    export let language = 'English';

    let isLoading = true;
    let audioUrl;

    onMount(async () => {
        await handleSubmit();
    });

    async function handleSubmit() {
        isLoading = true;
        audioUrl = null;
        const response = await fetch(BACKEND_URL + 'text-to-speech', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ text, language })
        });
        const r = await response.json();
        audioUrl = r.outputUri;
        isLoading = false;
    }
</script>

<div in:slide out:slide class = "flex {isRtlLanguage(language) ? 'justify-end' : ''}">
    {#if isLoading}
        <div class = "flex space-x-3">
            <div class = "pt-1">
                <Ping />
            </div>
            <div class = "text-sm text-gray">Generating voice response...</div>
        </div>
    {:else if audioUrl}
        <div class = "flex space-x-4">
            <div class = "rounded-full border border-lightgray">
                <audio controls>
                    <source src = {audioUrl} type = "audio/mp3">
                </audio>
            </div>
            <div class = "pt-4">
                <a href = {audioUrl} target = "_blank" class = "hovertext">
                    <i class = "bi bi-box-arrow-right"></i>
                </a>
            </div>
        </div>
    {/if}
</div>

🤔 А знаете ли вы, что...
HTML поддерживает встраивание аудио и видео с поддержкой встроенных проигрывателей.


60
1

Ответ:

Решено

Проблема устраняется, если я добавляю небольшую задержку между созданием URL-адреса аудиофайла S3 и подключением аудиоплеера: setTimeout(() => {isLoading = false}, 2000);.

Это дает достаточно времени, чтобы аудио-URL стал доступен аудиоплееру.

<script>
    import { onMount } from 'svelte';
    import { slide } from 'svelte/transition';
    import { BACKEND_URL } from '$lib/constants';
    import { isRtlLanguage } from '$lib/utils';
    import Ping from '$lib/components/loading/Ping.svelte';

    export let text = 'hello';
    export let language = 'English';

    let isLoading = true;
    let audioUrl;

    onMount(() => {
        handleSubmit();
    });

    async function handleSubmit() {
        isLoading = true;
        const response = await fetch(BACKEND_URL + 'text-to-speech', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ text, language })
        });
        const r = await response.json();
        audioUrl = r.outputUri;

        // give short delay until audio is ready.
        // this is to remedy a bug with the
        // S3 source on the audio player.
        setTimeout(() => {
            isLoading = false;
        }, 2000);
    }
</script>

<div in:slide out:slide class = "flex {isRtlLanguage(language) ? 'justify-end' : ''}">
    {#if isLoading}
        <div class = "flex space-x-3">
            <div class = "pt-1">
                <Ping />
            </div>
            <div class = "text-sm text-gray">Generating voice response...</div>
        </div>
    {:else}
        <div class = "rounded-full border border-lightgray">
            <audio controls>
                <source src = {audioUrl} type = "audio/mp3" />
            </audio>
        </div>
    {/if}
</div>

Интересные вопросы для изучения