Laravel livewire 3 和 javascript 来录制和接收音频

问题描述 投票:0回答:1

我使用 Laravel 10、Livewire 3 来完成此任务。录音按钮,单击后即可录制语音并保存。我还想保留页面渲染时记录预览的状态,以便我可以执行其他任务,例如在保存之前附加徽章。 我使用调度方法通过创建文件后的 JavaScript 来调用 livewire 方法, 每次我在链接音频文件时得到一个空数组,当我删除它并添加“测试”时,dd 响应是“测试”

过去两天我一直在尝试,但不明白为什么我没有捕捉到录制的文件。请检查下面我的代码

刀片:

<!-- Record/Stop Button with loading toggle -->
        <div class="custom-file-upload mb-4 pt-3 text-center">
            <button type="button" class="btn btn-primary btn-lg" id="recordButton">
                <i class="fas fa-microphone" id="micIcon"></i> <span id="recordButtonText">Start Recording</span>
            </button>
        </div>

        <!-- Duration Display -->
        <div id="durationDisplay" class="mt-2 text-center" style="font-size: 1.5rem; color: #333;"></div>

        <!-- Audio Preview -->
        <div class="mt-3 text-center">
            <audio id="audioPreview" controls hidden></audio>
        </div>

        <!-- Hidden Input for Livewire to Use -->
        <input type="file" wire:model="audio" id="audioInput" hidden>

        @error('audio')
        <span class="text-danger">{{ $message }}</span>
        @enderror

        <div class="form-group">
            <input type="text" class="form-control" wire:model="title" placeholder="Title">
            @error('title')
            <span class="text-danger">{{ $message }}</span>
            @enderror
        </div>

        

        <div class="d-flex justify-content-between align-items-center mt-4">
            <button type="button" class="btn btn-primary button-style" wire:click="store()" id="publishButton" disabled>
                <span wire:loading.remove wire:target="store">Publish Recording</span>
                <span wire:loading.class="d-block" wire:target="store" class="d-none"><i         class="fas fa-spinner fa-spin el-icon-loading"></i> Publishing...</span>
            </button>

            <span wire:loading.class="d-block" wire:target="store" class="text-info ml-3 d-        none">
                <i class="fas fa-spinner fa-spin el-icon-loading"></i> Saving your                 Recording...
            </span>
        </div>

        @if(session()->has('message'))
            <div class="alert alert-success mt-3">{{ session('message') }}</div>
        @endif
            </el-card>
        </div>
    </div>

组件记录.php

use Illuminate\Http\UploadedFile;
use Livewire\Component;
use Livewire\WithFileUploads;

use WithFileUploads;

public $title;
public $audio;
public $audioUrl;
protected $listeners = ['audioRecorded'];


public function audioRecorded($audio) // Accept audio directly
{
    dd($audio);
    // Check if audio is provided and is an instance of UploadedFile
    if ($audio instanceof UploadedFile) {
        // Process the audio file (e.g., save it to S3)
        dd("Audio received successfully", $audio);
    } else {
        dd("No audio data received.");
    }
}

我的Javascript

document.addEventListener('DOMContentLoaded', function () {
    const recordButton = document.getElementById('recordButton');
    const micIcon = document.getElementById('micIcon');
    const recordButtonText = document.getElementById('recordButtonText');
    const durationDisplay = document.getElementById('durationDisplay');
    const audioPreview = document.getElementById('audioPreview');
    const audioInput = document.getElementById('audioInput');

let mediaRecorder;
let audioChunks = [];
let isRecording = false;
let startTime;
let durationInterval;

recordButton.addEventListener('click', () => {
    if (!isRecording) {
        console.log("Starting recording...");
        startRecording();
    } else {
        console.log("Stopping recording...");
        stopRecording();
    }
});

function startRecording() {
    navigator.mediaDevices.getUserMedia({ audio: true })
        .then(stream => {
            mediaRecorder = new MediaRecorder(stream);
            mediaRecorder.start();
            audioChunks = [];
            startTime = new Date();
            isRecording = true;

            mediaRecorder.ondataavailable = event => {
                audioChunks.push(event.data);
            };

            mediaRecorder.onstop = () => {
                const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
                const audioUrl = URL.createObjectURL(audioBlob);

                // Set the preview audio and make it visible
                audioPreview.src = audioUrl;
                audioPreview.hidden = false;

                // Create a File object
                const audioFile = new File([audioBlob], 'recording.wav', { type: 'audio/wav' });

                // Dispatch the audio file directly
                Livewire.dispatch('audioRecorded', { audio: audioFile }); // Send the audio file directly

                // Enable the Publish button
                document.getElementById('publishButton').disabled = false;
            };



            micIcon.classList.replace('fa-microphone', 'fa-stop');
            recordButtonText.textContent = "Stop Recording";
            durationInterval = setInterval(updateDuration, 1000);
        })
        .catch(error => {
            console.error("Error accessing microphone:", error);
            alert("Microphone access denied or unavailable.");
        });

    durationDisplay.textContent = "00:00";
}

function stopRecording() {
    if (mediaRecorder && mediaRecorder.state !== "inactive") {
        mediaRecorder.stop();
        clearInterval(durationInterval);
        isRecording = false;

        micIcon.classList.replace('fa-stop', 'fa-microphone');
        recordButtonText.textContent = "Start Recording";
    }
}

function updateDuration() {
    const elapsedSeconds = Math.floor((new Date() - startTime) / 1000);
    const minutes = String(Math.floor(elapsedSeconds / 60)).padStart(2, '0');
    const seconds = String(elapsedSeconds % 60).padStart(2, '0');
    durationDisplay.textContent = `${minutes}:${seconds}`;
}

function createFileList(file) {
    const dataTransfer = new DataTransfer();
    dataTransfer.items.add(file);
    return dataTransfer.files;
}
});
javascript php laravel-livewire livewire-3
1个回答
0
投票

实际上遇到了同样的问题:/

© www.soinside.com 2019 - 2024. All rights reserved.