我在 Blazor 服务器中,当我单击音频标签时,它不播放任何声音。但当我在 Android 或 Windows PC 上单击它时,它运行良好。
这是我的代码:
@if (Question.Parcours.Type == Constants.TypeLanguage)
{
<div class="d-flex flex-column align-items-start">
@if (FileAudio != null)
{
<audio class="m-1" controls src="@FileAudio" />
}
@if (Managing)
{
@if (recording)
{
<h2 class="m-1 alert-danger">En cours d'enregistrement...</h2>
<button type="button" class="btn btn-secondary m-3" disabled="@DisableStopRecoredingBtn" @onclick="StopRecording">
<i class="bi bi-mic-mute-fill"></i> Arrêter d'enregistrer l'audio
</button>
}
else
{
<button type="button" class="btn btn-primary m-3" @onclick="StartRecording">
<i class="bi bi-mic-fill"></i> Commencer à enregistrer l'audio
</button>
}
}
</div>
@if (ErrorMessage != null)
{
<span class="alert-danger">@ErrorMessage</span>
}
}
@code {
[Parameter] public QuestionDto Question { get; set; }
[Parameter] public bool Managing { get; set; } = true;
[Inject] IJSRuntime JS { get; set; }
private byte[] audioBytes;
private bool recording = false;
private string? FileAudio { get; set; }
private bool DisableStopRecoredingBtn { get; set; } = false;
private string AudioDirectory = Path.Combine("Fichiers", "AudiosLangue");
private string? ErrorMessage { get; set; } = null;
private string MessagePermissionDenied = "Vous devez permettre à l'application d'accéder à votre micro!";
protected override async Task OnInitializedAsync()
{
if (Question?.AudioFilePath != null)
{
var audioStream = GetAudioFileStream(Question.AudioFilePath);
if (audioStream != null)
FileAudio = await GetBase64Audio(audioStream);
}
}
private async Task StartRecording()
{
try
{
ErrorMessage = null;
await JS.InvokeVoidAsync("startRecording");
recording = true;
StateHasChanged();
await Task.Delay(60000);
if (recording)
{
await StopRecording();
}
}
catch (Exception ex)
{
ErrorMessage = MessagePermissionDenied;
}
}
private async Task StopRecording()
{
try
{
DisableStopRecoredingBtn = true;
audioBytes = await JS.InvokeAsync<byte[]>("stopRecording");
const int maxFileSize = 5 * 1024 * 1024;
if (audioBytes.Length > maxFileSize)
{
ErrorMessage = "Le fichier est trop gros, le maximum est de 5 MB.";
return;
}
if (!Directory.Exists(AudioDirectory))
{
Directory.CreateDirectory(AudioDirectory);
}
var randomFileName = $"P{Question.ParcoursId}-Q{Question.Id}-{Path.GetRandomFileName()}.mp3";
var filePath = Path.Combine(AudioDirectory, randomFileName);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
await File.WriteAllBytesAsync(filePath, audioBytes);
Question.AudioFilePath = filePath;
var fileStream = GetAudioFileStream(filePath);
FileAudio = await GetBase64Audio(fileStream);
recording = false;
DisableStopRecoredingBtn = false;
StateHasChanged();
}
catch (Exception ex)
{
ErrorMessage = MessagePermissionDenied;
}
}
private Stream GetAudioFileStream(string filePath)
{
if (File.Exists(filePath))
{
return new FileStream(filePath, FileMode.Open, FileAccess.Read);
}
return null;
}
private async Task<string> GetBase64Audio(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
byte[] byteArray = memoryStream.ToArray();
string base64String = Convert.ToBase64String(byteArray);
return $"data:audio/mp3;base64,{base64String}";
}
}
}
因此,使用音频标签播放声音是行不通的。你能帮助我吗?奇怪的是,当我在IOS上录制时,我可以点击音频并且播放声音很好。貌似get文件不行?当我注册时,我可以听到声音。但如果我回来时音频文件不在这里并且需要加载,这在 ios 上不起作用。我对 Ios 的转换是否错误?
这是针对此类移动问题的规则 - 仅当您在屏幕上实际单击时,它才会接受客户端确实想要通过 JavaScript 加载/播放数据。 这是设计使然,旨在保护开发者免于通过自动播放广告等方式浪费移动数据。
您可以尝试通过不同的级别来克服这个问题:
<audio>
有条件渲染。 立即使用 1 秒无声音频文件进行渲染。 显然,一个谨慎的操作系统不会让你随时创建和播放新的声音对象。
我的理解是,新的苹果操作系统版本在媒体控制方面更加慷慨。 有旧产品吗?