У меня есть приложение для записи, которое записывает действия пользователя при нажатии кнопки мыши и воспроизводит звук при нажатии кнопки мыши. Оно также выполняет различные операции с записью на серверной стороне, но на стороне клиента это почти все.
Во всяком случае, до тех пор, пока ios 17, все работало нормально - я создавал запись с помощью MediaRecorder, настраивал поддерживаемые параметры для каждого браузера, и пользователь мог сразу записывать и воспроизводить себя. Я знаю о строгих правилах Apple, запрещающих автозапуск, но, поскольку для начала и завершения записи пользователю придется взаимодействовать со страницей, это было сочтено достаточно хорошим.
Однако теперь это не так. и я не понимаю, почему.
Я добавил несколько подписчиков на события, чтобы посмотреть, что происходит, и по какой-то причине причина, по которой он не воспроизводится, заключается в том, что собственный элемент аудио находится в состоянии готовности. никогда не превышает 0, даже если для него вызывается функция load().
Исследование как объекта записи, так и самого объекта не показывает ничего необычного, объект содержит данные и имеет правильный звук формат для ios, плюс URL-адрес кажется правильным и, конечно же, код буквально работает везде. но ничего не меняет того факта, что на ios состояние готовности не превышает 0.
Я добавил еще несколько подписчиков событий, но ничего не вызывается, кроме «загруженных метаданных», и все. ни ошибок, ни прогресса, ничего — опять же только на ios 17+.
Наконец, я добавил кнопку отладки, которая вызывает воспроизведение аудиоэлемента при нажатии — и, очевидно, это работает. это ломает другие вещи, но я не особо вникал в это. Суть в том, что тот же объект, тот же аудиоэлемент, та же запись - загружается и работает при конкретном нажатии.
мой тогда вопрос в том, так ли это? предотвращает ли ios загрузку данных, если событие щелчка не связано напрямую с воспроизведением звука? почему «onmouseup» не считается достаточно хорошим взаимодействием с пользователем, учитывая, что игра происходит внутри этого ответчика событий? почему не появляется никакой ошибки, указывающей, что происходит и почему? есть ли у кого-нибудь идеи, в чем здесь может быть проблема?
Код:
Код: Выделить всё
const mp3BlobPromise = this.recording.end()
.then(async (Blob) => {
try {
console.log('recroding ended, blob acquired', Blob)
this.setAudio.emit(Blob);
// hear the recording immediately
this.audio.nativeElement.src = this.createObjectURL(Blob); // URL.createObjectURL(Blob);
this.audio.nativeElement.autoplay = false; //should always be false
this.audio.nativeElement.load();
const waitForMediaReady = new Promise((resolve) => {
console.log('waiting on media ready... ')
console.log('Current readyState:', this.audio.nativeElement.readyState);
console.log('audio bloc url: ', this.audio.nativeElement.src)
this.audio.nativeElement.addEventListener('readystatechange', (event) => {
if (this.audio.nativeElement.readyState >= 2) {
console.log('readystatechange event fired');
resolve();
}
}, { once: true });
});
const nativeElement = this.audio.nativeElement
nativeElement.addEventListener('loadedmetadata', () => {
console.log('Audio metadata loaded');
});
nativeElement.addEventListener('error', (e) => {
console.error('Error with audio playback:', nativeElement.error);
console.error(e);
});
nativeElement.addEventListener("canplay", (event) => {
console.log('can play')
});
nativeElement.addEventListener('stalled', () => {
console.log('Playback stalled');
});
nativeElement.addEventListener('waiting', () => {
console.log('Waiting for data');
});
waitForMediaReady.then(() => {
console.log('media is ready, trying to play')
var isPlaying = nativeElement.currentTime > 0 && !nativeElement.paused && !nativeElement.ended
&& nativeElement.readyState > nativeElement.HAVE_CURRENT_DATA
if (!isPlaying) {
this.audio.nativeElement.play().then(() => {
console.log('audio has played, nice')
this.isAudioPlayed = true;
}).catch(err => {
console.error('Native element play error: ', err);
this.showPlayButton();
});
this.selfAudioPlayStart.emit();
}
})
} catch (err) {
console.error('Record button error: ', err);
}
})
.catch(error => {
this.mic.ensureInit();
this.MouseUp.emit(null);
this.setAudio.emit(null);
console.log('an error occured while ending the recording.', error)
return null;
});
Источник: https://stackoverflow.com/questions/781 ... os-17-read
Мобильная версия