Telegram не воспроизводится, записанный голосом Safari

Здравствуйте, у меня есть небольшое веб-приложение, в котором клиент может оставить отзыв о ресторане. Есть возможность записать голосовую заметку. Когда я записываю голос в Chrome, Firefox, Opera. На Mac или Windows все работает, и я слышу голос, отправленный боту Telegram. Но запись в Safari voice воспроизводится без голоса. В IOS та же проблема в браузерах Chrome и Safari.

Вот мой код:

  const mic_btn = document.querySelector("#record__button");
  const playback = document.querySelector(".playback");
  const voiceRemove = document.getElementById("removeVoive");
  const voiceBody = document.querySelector(".record__body");
  const openRecorder = document.querySelector(".record__open-recorder");

  let counter = document.getElementById("counter");

  openRecorder.addEventListener("click", () => {
    voiceBody.classList.add("_active");
    setupAudio();
  });

  mic_btn.addEventListener("click", toggleMic);

  voiceRemove.addEventListener("click", () => {
    voiceRemove.classList.remove("_active");
    playback.classList.remove("_active");
    playback.src = "";
    counter.innerHTML = "1:00";
  });

  let can_record = false;
  let is_recording = false;
  let recorder = null;

  let chuncs = [];
  let voice = [];

  function setupAudio() {
    console.info("Sterted");
    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices
        .getUserMedia({
          audio: true,
        })
        .then(setupStream)
        .catch((err) => {
          console.error(err);
        });
    }
  }

  function setupStream(stream) {
    recorder = new MediaRecorder(stream);

    recorder.ondataavailable = (e) => {
      chuncs.push(e.data);
      voice.push(e.data);
    };
    recorder.onstop = () => {
      const blob = new Blob(chuncs, { type: "audio/wav" });
      chuncs = [];
      const audioUrl = window.URL.createObjectURL(blob);
      
      playback.src = audioUrl;
      playback.classList.add("_active");
      voiceRemove.classList.add("_active");
    };

      can_record = true;
  }

  let count;
  let recordingInterval;

  function toggleMic() {
    if (!can_record) return;

    is_recording = !is_recording;

    if (is_recording) {
      recorder.start();
      mic_btn.classList.add("is-recording");
      count = true;
      if (count) {
        recordingInterval = setInterval(() => {
          recorder.stop();
          mic_btn.classList.remove("is-recording");
          count = false;
        }, 60000);
      }
      tick();
    } else {
      recorder.stop();
      mic_btn.classList.remove("is-recording");
      count = false;
      clearInterval(recordingInterval);
    }
  }
  // Timer
  let seconds = 60;

  // Count down timer function
  function tick() {
    if (count) {
      seconds--;
      counter.innerHTML = "0:" + (seconds < 10 ? "0" : "") + String(seconds);
      if (seconds > 0) {
        setTimeout(tick, 1000);
      }
    } else {
      seconds = 60;
    }
  }

  const form = document.getElementById('form-main');
  
  form.addEventListener('submit', formSend);

  async function formSend(e) {
    e.preventDefault(); 
    
    const audioBlob = new Blob(voice, { type: 'audio/mp4; codecs=opus'  });
    voice = [];

    let error = formValidate(form);
    let formData = new FormData(form);
    formData.append('image', formImage.files[0]);
    formData.append("audio_file", audioBlob, "voice.mp4");
    
    if (error === 0) {
      form.classList.add('_sending');

      let response = await fetch('/save', {
          method: 'POST',
          cache: 'no-cache',
          body: formData,
        });
        if (response.ok) {
          let result = await response.json();
          form.reset();
          form.classList.remove('_sending');
           
        } else {
         console.info('Error');
         form.classList.remove('_sending');
        } 
      } else {
        console.error('error');
      }
    }

И PHP:

if (isset($_FILES["audio_file"])) {
    $voice = $_FILES["audio_file"];
    $voice_tmp = $voice["tmp_name"];
    $voice_name = $voice["name"];

    // File info
    $temp_voice = explode(".", $voice_name);
    $new_voice_name = round(microtime(true)) . '.' . end($temp_voice);
}
// Save voice  and sending to a telegram
if (!empty($voice_name) && $voice['error'] === UPLOAD_ERR_OK) {
    $upload_voice_path = 'assets/uploads/audio/'; 
    $upload_voice_path = $upload_voice_path.basename( $new_voice_name );
    // debug($upload_voice_path);
    move_uploaded_file( $voice_tmp, $upload_voice_path );
    // Send audio to telegram
    send_to_telegram($api_token, 'sendAudio', $chat_id, 'audio', $upload_voice_path);
}

function send_to_telegram($api_token, $send_type, $chat_id, $type, $file_path) {
    // Sending file to telegrab bot
    $bot_url = "https://api.telegram.org/bot" . $api_token ."/";
    $url = $bot_url . $send_type ."?chat_id = " . $chat_id ;
    $post_fields = ['chat_id'   => $chat_id,
    $type     => new CURLFile(realpath($file_path)),
];
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Content-Type:multipart/form-data"
    ));
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); 
    $output = curl_exec($ch);
}

Я пробовал менять кодеки, формат файла, но проблема осталась та же.

Дело в том, что это может быть проблема с разрешениями. Разрешили ли вы доступ к микрофону на сайте? Использует ли ваш сайт HTTPS? Некоторые из этих JS API, такие как API геолокации, не работают без включенного HTTPS, и это может быть проблемой для браузеров на iOS.

Eduard 07.05.2024 21:57

Да, все разрешения предоставлены. И самое интересное, что я только что проверил. Запись, которую я не слышу в Telegram iOS, отлично работает в Telegram Android.

Yevhenii Malyshko 07.05.2024 22:17
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, проблема не в Telegram или вашем PHP-коде. Когда код PHP может передать записанный Google Chrome звук боту Telegram, это означает, что с серверной частью все в порядке.

Вам следует проверить свой браузер Safari с помощью онлайн-инструментов для проверки микрофона, таких как webcammictest.com, чтобы убедиться, что все в порядке.

Если все в порядке, вам следует обеспечить совместимость JavaScript-кода вашего аудиомагнитофона, чтобы устранить проблему.

Я надеюсь, что это помогает.

Спасибо! Это было полезно. Я переписал код на JS и использовал этот рекордер для своего проекта: github.com/ai/audio-recorder-polyfill/tree/main

Yevhenii Malyshko 12.05.2024 19:26

Другие вопросы по теме