• Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    Вадим, выбрал один для себя скрипт)
    Но вот проблема ещё одна)
    у меня на странице идёт код:
    <div id="1">Первый элемент <button>Записать аудио</button><div>
    <div id="2">Второй элемент <button>Записать аудио</button><div>
    <div id="3">Третий элемент <button>Записать аудио</button><div>


    А во всех примерах всегда только 1 div, одна кнопка... И вот можно ли как-то так сделать, чтобы при нажатии любой из этих начиналась запись и что самое главное - записи сохранялись в нужный div? То есть если 2 кнопка нажата, то во второй div и тд..

    Вот с этим кодом вообще не пойму, как такое реализовать... Или вариант только копировать для каждого div - свой скрипт? просто тогда html будет огромный получаться..
    var recordButton = document.getElementById("recordButton");
    var stopButton = document.getElementById("stopButton");
    var pauseButton = document.getElementById("pauseButton");
    
    //add events to those 2 buttons
    recordButton.addEventListener("click", startRecording);
    stopButton.addEventListener("click", stopRecording);
    pauseButton.addEventListener("click", pauseRecording);
  • Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    Вадим, спасибо большое!
  • Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    Вадим, да, по этой инструкции и делал
    mediaRecorder.addEventListener("stop", function() {
        const voiceBlob = new Blob(voice, {
            type: 'audio/wav'
        });


    вот тут устанавливают тип записи
    но эта строчка просто указывает тип для названия (чтобы сохранил как .mp3 // .wav и тд), а на самом устройство автоматически выбирает формат для записи
    и проблема в том, что windows компьютеры пишут в OGG в итоге, а айфоны в AAP
    OGG - на айфонах не воспроизводится в
    нужен какой-то единый формат, который на всех устройствах поддерживается
  • Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    <script>
                            var res<?=$q_idSave?> = '';
                            const URLaudio<?=$q_idSave?> = 'voice.php?AnswerID=<?=$q_idSave?>';
                            let div<?=$q_idSave?> = document.createElement('div');
                            div<?=$q_idSave?>.id = 'messages<?=$q_idSave?>';
                            div<?=$q_idSave?>.style.display = 'flex';
                            let root<?=$q_idSave?> = document.createElement('button');
                            root<?=$q_idSave?>.id = 'root<?=$q_idSave?>';
                            root<?=$q_idSave?>.innerHTML = 'Предоставить доступ к микрофону';
                            root<?=$q_idSave?>.className = 'btn btn-soft-primary btn-xs';
                            let start<?=$q_idSave?> = document.createElement('button');
                            start<?=$q_idSave?>.id = 'start<?=$q_idSave?>';
                            start<?=$q_idSave?>.innerHTML = 'Записать голосовой комментарий';
                            start<?=$q_idSave?>.className = 'btn btn-soft-primary btn-xs';
                            let stop<?=$q_idSave?> = document.createElement('button');
                            stop<?=$q_idSave?>.id = 'stop<?=$q_idSave?>';
                            stop<?=$q_idSave?>.innerHTML = '<div class="spinner-grow text-white recload" role="status">\n<span class="sr-only">Записываем...</span>\n</div> Остановить запись';
                            stop<?=$q_idSave?>.className = 'btn btn-danger btn-xs';
                            let divComm<?=$q_idSave?> = document.querySelector('#audioComm<?=$q_idSave?>');
                            divComm<?=$q_idSave?>.appendChild(div<?=$q_idSave?>);
                            divComm<?=$q_idSave?>.appendChild(root<?=$q_idSave?>);
                            divComm<?=$q_idSave?>.appendChild(start<?=$q_idSave?>);
                            divComm<?=$q_idSave?>.appendChild(stop<?=$q_idSave?>);
                            document.getElementById('stop<?=$q_idSave?>').style.display='none';
                            document.getElementById('start<?=$q_idSave?>').style.display='none';
                            document.querySelector('#root<?=$q_idSave?>').addEventListener('click', function() {
                                document.getElementById('start<?=$q_idSave?>').style.display='block';
                                document.getElementById('root<?=$q_idSave?>').style.display='none';
                                //var options = {mimeType: 'audio/mp3'};
                                navigator.mediaDevices.getUserMedia({audio: true})
                                    .then(stream => {
                                        const mediaRecorder = new MediaRecorder(stream);
    
                                        document.querySelector('#start<?=$q_idSave?>').addEventListener('click', function () {
                                            mediaRecorder.start();
                                            document.getElementById('start<?=$q_idSave?>').style.display = 'none';
                                            document.getElementById('stop<?=$q_idSave?>').style.display = 'block';
                                        });
                                        let audioChunks = [];
                                        mediaRecorder.addEventListener("dataavailable", function (event) {
                                            audioChunks.push(event.data);
                                        });
    
                                        document.querySelector('#stop<?=$q_idSave?>').addEventListener('click', function () {
                                            mediaRecorder.stop();
                                            document.getElementById('stop<?=$q_idSave?>').style.display = 'none';
                                        });
    
                                        mediaRecorder.addEventListener("stop", function () {
                                            const audioBlob = new Blob(audioChunks, {type: 'audio/mp3'});
    
                                            //Конвертация
                                            channels = 1; //1 for mono or 2 for stereo
                                            sampleRate = 44100; //44.1khz (normal mp3 samplerate)
                                            kbps = 128; //encode 128kbps mp3
                                            mp3encoder = new lamejs.Mp3Encoder(channels, sampleRate, kbps);
                                            var mp3Data = [];
                                            const fr = new FileReader();
                                            fr.readAsArrayBuffer(audioBlob);
                                            fr.onload = function() {
                                                res<?=$q_idSave?> = fr.result;
                                                console.log(res<?=$q_idSave?>);
                                                data_16 = new Int16Array(res<?=$q_idSave?>);
                                                console.log(data_16);
                                                samples = new Int16Array(data_16);
                                                sampleBlockSize = 1152; //can be anything but make it a multiple of 576 to make encoders life easier
                                                var mp3Data = [];
                                                for (var i = 0; i < samples.length; i += sampleBlockSize) {
                                                    sampleChunk = samples.subarray(i, i + sampleBlockSize);
                                                    var mp3buf = mp3encoder.encodeBuffer(sampleChunk);
                                                    if (mp3buf.length > 0) {
                                                        mp3Data.push(mp3buf);
                                                    }
                                                }
                                                var mp3buf = mp3encoder.flush();   //finish writing mp3
                                                if (mp3buf.length > 0) {
                                                    mp3Data.push(new Int16Array(mp3buf));
                                                }
                                                var blobR = new Blob(mp3Data, {type: 'audio/mp3'});
                                                let fd = new FormData();
                                                fd.append('voice', blobR);
                                                sendVoice(fd);
                                                audioChunks = [];
                                            };
                                        });
                                    });
                            });
    
                            async function sendVoice(form) {
                                let promise = await fetch(URLaudio<?=$q_idSave?>, {
                                    method: 'POST',
                                    body: form});
                                if (promise.ok) {
                                    let response =  await promise.json();
                                    console.log(response.data);
                                    let audio<?=$q_idSave?> = document.createElement('audio');
                                    audio<?=$q_idSave?>.src = response.data;
                                    audio<?=$q_idSave?>.controls = true;
                                    document.querySelector('#messages<?=$q_idSave?>').appendChild(audio<?=$q_idSave?>);
                                    let delB<?=$q_idSave?> = document.createElement('a');
                                    delB<?=$q_idSave?>.href = '<?=$url?>/lk/delAudio/<?=$q_idSave?>/<?=$redact?>';
                                    delB<?=$q_idSave?>.innerHTML = 'Удалить';
                                    delB<?=$q_idSave?>.className = 'btn btn-xs btn-danger';
                                    delB<?=$q_idSave?>.style.marginBottom = '2%';
                                    delB<?=$q_idSave?>.style.marginTop = '1%';
                                    document.querySelector('#messages<?=$q_idSave?>').appendChild(delB<?=$q_idSave?>);
                                }
                            }
                        </script>


    Там кода много...)
    А может быть есть ещё какой-то вариант, как сразу записывать микрофон пользователя на сайте в MP3?
  • Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    Вадим, пробовал, так не получается :(
    Там получается у меня идёт запись аудио, данные в blob передаются в формате int8 и мне их нужно преобразовать в int16 (для перекодировки в формат .mp3) и для сохранения

    В общем нужно как-то этот fr.result преобразовать в формат int16, но чтобы его преобразовывать - нужно сначала как-то вытащить...
  • Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    Вадим,
    Спасибо большое! А как можно получить вот этот массив?
    602fbcb352c6a510025996.png
  • Как правильно использовать FileReader()?

    @nikita2585 Автор вопроса
    var res = '';
    const fr = new FileReader();
    fr.readAsArrayBuffer(audioBlob);
    fr.onload = function() {
       res = fr.result;
    };
    console.log(res);


    Спасибо!) Но почему-то в таком случае возвращается не null, а просто пустая строка... Можно как-то из этой функции записать массив в переменную?
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    Kovalsky, я думаю, что скорее всего либо samples не так передаю, может нужен какой-то особый формат тоже? Или наоборот в POST нужно не mp3r отправлять, а что-то другое
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    Kovalsky, через lamejs пытаюсь преобразовать в mp3, но в результате PHP возвращает пустую строку

    Скорее всего какие-то переменные ввожу неверно?

    mediaRecorder.addEventListener("stop", function () {
                                            const audioBlob = new Blob(audioChunks, {type : 'audio/mp3' });
                                            let fd = new FormData();
                                            fd.append('voice', audioBlob);
                                            sendVoice(fd);
                                            audioChunks = [];
                                        });

    async function sendVoice(form) {
                                var mp3Data = [];
    
                                var mp3encoder = new lamejs.Mp3Encoder(1, 44100, 128); //mono 44.1khz encode to 128kbps
                                var samples = form; //one second of silence replace that with your own samples
                                var mp3Tmp = mp3encoder.encodeBuffer(samples); //encode mp3
    
                                //Push encode buffer to mp3Data variable
                                mp3Data.push(mp3Tmp);
    
                                // Get end part of mp3
                                mp3Tmp = mp3encoder.flush();
    
                                // Write last data to the output data, too
                                // mp3Data contains now the complete mp3Data
                                mp3r = mp3Data.push(mp3Tmp);
    
                                let promise = await fetch(URLaudio<?=$q_idSave?>, {
                                    method: 'POST',
                                    body: mp3r});
    //... ненужный код
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    rPman, да, проблема действительно в этом
    То, что записывает айфон:
    602abb389a698669412833.png

    То, что записывает компьютер:
    602abb6344309175092544.png

    Только я не пойму... почему так происходит? Ведь JS код один выполняется...
    Как это можно исправить? :((
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    rPman, отправить то, что в итоге записывается с компьютера и с телефона, да? (аудиофайл)
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    Kovalsky, не очень понял, где найти репозиторий)
    https://github.com/Krivodanov/Voice-comments - за основу брал этот проект там вроде все файлы на сервере хранятся
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    Вадим, тоже самое((
    602a7bda4c1db070303002.jpeg вот так отображает

    602a7bee6912c837384946.png mediaRecorder вроде верно настроен
  • Почему записанный через компьютер аудиофайл не работает на айфонах?

    @nikita2585 Автор вопроса
    Вадим, да :( в этом и проблема...
    С айфона записывается для всех устройств, а с компьютера (пробовал на нескольких) - только для windows...