JS. Запись потокового звука в Chrome и его воспроизведение в Safari

Есть скрипт для запуска потоковой записи аудио в браузере и последующей ее загрузке на сервер

navigator.mediaDevices.getUserMedia({audio: true})
.then(stream => {
    const mediaRecorder = new MediaRecorder(stream)
    let audioChunks = []

    mediaRecorder.addEventListener('dataavailable', e => audioChunks.push(e.data))

    document.addEventListener('click', e => {

        // начало записи
        if (e.target.closest('.dialogs-footer__area-voice')) {
            area.classList.add('_rec')
            textarea.setAttribute('disabled', '')
            start()
            mediaRecorder.start()

        // конец записи
        } else if (e.target.closest('.dialogs-footer__area-stop')) {
            area.classList.remove('_rec')
            textarea.removeAttribute('disabled')
            clearInterval(interval)
            min = sec = ms = 0
            mediaRecorder.stop()
        }
    })

    mediaRecorder.addEventListener("stop", async () => {
        const formData = new FormData(),
            audioBlob = new Blob(audioChunks, {
            type: 'audio/mp3'
        })

        let axiosResponse;

        formData.append('action', 'rec')
        formData.append('voice', audioBlob)

        await axios.post(URL, formData)
        .then(response => {
            console.log(response.data);
            axiosResponse = response.data
        })

        const todayChat = document.querySelector('.dialogs-body__day._today'),
            newMessage = document.createElement('div')

        newMessage.className = 'dialogs-body__manager'
        newMessage.innerHTML = `
            <div class="dialogs-body__manager-audio audio">
                <div class="audio__info">
                    <p class="audio__info-name">${axiosResponse.name}</p>
                    <p class="audio__info-date">${axiosResponse.time}</p>
                </div>
                <div class="audio__item">
                    <div class="audio__item-inner">
                        <audio class="audio__item-audio" controls>
                            <source src="/uploads/${axiosResponse.title}">
                        </audio>
                        <div class="audio__item-button"></div>
                        <div class="audio__item-progress"></div>
                        <div class="audio__item-time"></div>
                    </div>
                </div>
            </div>`

        if (todayChat) {
            todayChat.append(newMessage)
            scrollDown('.dialogs-body__chat')
        } else {
            createtodayChat().append(newMessage)
            scrollDown('.dialogs-body__chat')
        }

        initAudio(newMessage)

        audioChunks = []
    })
})

function initAudio(audioItem) {
    let finishItem = audioItem.querySelector('.audio__item-time'),
        audioFile = audioItem.querySelector('.audio__item-audio'),
        slider = audioItem.querySelector('.audio__item-progress')
    
    if (audioFile.duration) {
        foo()
    } else {
        audioFile.addEventListener('loadedmetadata', foo)
    }
        
    function foo() {
        if (audioFile.duration === Infinity) {
            audioFile.currentTime = 1e101;
            
            audioFile.ontimeupdate = function() {
                this.ontimeupdate = () => {
                    return;
                }
                
                audioFile.currentTime = 0;
                
                createSlider()
            }
            return
        }
            
        createSlider()
        
        function createSlider() {
            noUiSlider.create(slider, {
                start: 0,
                connect: 'lower',
                range: {
                    'min': 0,
                    'max': audioFile.duration
                }
            })
            
            audioItem.querySelector('.noUi-origin').setAttribute('disabled', true)
            finishItem.innerText = String.prototype.toMMSS(audioFile.duration.toString())
        }
    }
}

в php этот файл принимается, переносится в нужное место и возвращается его имя

if ($_POST['action'] === 'rec') {
    $path = $_SERVER['DOCUMENT_ROOT'] . '/uploads/';
    $type_file = explode('/', $_FILES['voice']['type'])[1];

    if (move_uploaded_file($_FILES['voice']['tmp_name'], $path . date('YmdHis') . '.' . $type_file)) {
        // Далее можно сохранить название файла в БД и т.п.
        $response = [
            'name' => $arr['name'],
            'time' => $arr['time'],
            'title' => date('YmdHis') . '.' . $type_file
        ];
        echo json_encode($response);
    }
}

В инициализации, как видно, я проверяю длину файла на бесконечность, т.к. из-за бага Chrome именно такая длина аудио возвращается. Вопрос следующий: все везде работает прекрасно, но записанные в Chrome аудио не работают в Safari. Проблема, насколько я понял, давняя. Есть ли возможность как то решить ее?

Решено.


Ответы (0 шт):