Visualizzazione dei risultati da 1 a 9 su 9

Discussione: Creare waveform audio

  1. #1

    Creare waveform audio

    Ciao a tutti.
    Ho preso questo script da css-tricks.com per visualizzare un onda audio dei file mp3

    codice:
    // Set up audio context
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    const audioContext = new AudioContext();
    
    
    /**
     * Retrieves audio from an external source, the initializes the drawing function
     * @param {String} url the url of the audio we'd like to fetch
     */
    const drawAudio = url => {
        fetch(url)
            .then(response => response.arrayBuffer())
            .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
            .then(audioBuffer => draw(normalizeData(filterData(audioBuffer))));
    };
    
    
    /**
     * Filters the AudioBuffer retrieved from an external source
     * @param {AudioBuffer} audioBuffer the AudioBuffer from drawAudio()
     * @returns {Array} an array of floating point numbers
     */
    const filterData = audioBuffer => {
        const rawData = audioBuffer.getChannelData(0); // We only need to work with one channel of data
        const samples = 70; // Number of samples we want to have in our final data set
        const blockSize = Math.floor(rawData.length / samples); // the number of samples in each subdivision
        const filteredData = [];
        for (let i = 0; i < samples; i++) {
            let blockStart = blockSize * i; // the location of the first sample in the block
            let sum = 0;
            for (let j = 0; j < blockSize; j++) {
                sum = sum + Math.abs(rawData[blockStart + j]); // find the sum of all the samples in the block
            }
            filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
        }
        return filteredData;
    };
    
    
    /**
     * Normalizes the audio data to make a cleaner illustration 
     * @param {Array} filteredData the data from filterData()
     * @returns {Array} an normalized array of floating point numbers
     */
    const normalizeData = filteredData => {
        const multiplier = Math.pow(Math.max(...filteredData), -1);
        return filteredData.map(n => n * multiplier);
    }
    
    
    /**
     * Draws the audio file into a canvas element.
     * @param {Array} normalizedData The filtered array returned from filterData()
     * @returns {Array} a normalized array of data
     */
    const draw = normalizedData => {
        // set up the canvas
        const canvas = document.querySelector(".waveform");
        const dpr = window.devicePixelRatio || 1;
        const padding = 20;
        canvas.width = canvas.offsetWidth * dpr;
        canvas.height = (canvas.offsetHeight + padding * 2) * dpr;
        const ctx = canvas.getContext("2d");
        ctx.scale(dpr, dpr);
        ctx.translate(0, canvas.offsetHeight / 2 + padding); // set Y = 0 to be in the middle of the canvas
    
    
        // draw the line segments
        const width = canvas.offsetWidth / normalizedData.length;
        for (let i = 0; i < normalizedData.length; i++) {
            const x = width * i;
            let height = normalizedData[i] * canvas.offsetHeight - padding;
            if (height < 0) {
                height = 0;
            } else if (height > canvas.offsetHeight / 2) {
                height = height > canvas.offsetHeight / 2;
            }
            drawLineSegment(ctx, x, height, width, (i + 1) % 2);
        }
    };
    
    
    /**
     * A utility function for drawing our line segments
     * @param {AudioContext} ctx the audio context 
     * @param {number} x  the x coordinate of the beginning of the line segment
     * @param {number} height the desired height of the line segment
     * @param {number} width the desired width of the line segment
     * @param {boolean} isEven whether or not the segmented is even-numbered
     */
    const drawLineSegment = (ctx, x, height, width, isEven) => {
        ctx.lineWidth = 1; // how thick the line is
        ctx.strokeStyle = "#fff"; // what color our line is
        ctx.beginPath();
        height = isEven ? height : -height;
        ctx.moveTo(x, 0);
        ctx.lineTo(x, height);
        ctx.arc(x + width / 2, height, width / 2, Math.PI, 0, isEven);
        ctx.lineTo(x + width, 0);
        ctx.stroke();
    };
    
    drawAudio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/shoptalk-clip.mp3');
    ma mi da i seguenti errori:
    SyntaxError: Identifier 'drawAudio' has already been declared

    e

    Uncaught (in promise) ReferenceError: audioContext is not defin

    eppure faccio un copia ed incolla mah
    Ultima modifica di techno; 26-05-2021 a 11:55

  2. #2
    Utente di HTML.it L'avatar di ninja72
    Registrato dal
    May 2020
    residenza
    -
    Messaggi
    319
    Esistono molte librerie gratuite per il tuo scopo, ti mando le prime due che ho trovato.
    Audiomotion-analyzer e Wavesurfer.

    codice:
    <!DOCTYPE html>
    <html lang="it-IT">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            canvas {
                width: 300px;
                height: 65px;
            }
    
            .audioblock {
                width: 300px;
            }
    
            #waveform {
                width: 300px;
            }
        </style>
    </head>
    
    <body>
    
        <div class="audioblock">
            <div id="container"></div>
            <audio src="Alpha.mp3" id="audio" controls crossorigin></audio>
        </div>
    
        <div id="waveform"></div>
        <button id="playpause">Play / Pause</button>
    
        <script src="https://unpkg.com/wavesurfer.js/dist/wavesurfer.js"></script>
      
      <script type="module">
            // load module from Skypack CDN
            import AudioMotionAnalyzer from 'https://cdn.skypack.dev/audiomotion-analyzer?min'
    
            window.addEventListener('DOMContentLoaded', () => {
                // audio source
                const audioEl = document.getElementById('audio')
    
                // instantiate analyzer
                const audioMotion = new AudioMotionAnalyzer(
                    document.getElementById('container'),
                    {
                        source: audioEl,
                        height: window.innerHeight - 50,
                        mode: 5,
                        gradient: 'prism', //classic / prism / rainbow
                        lineWidth: 2,
                        fillAlpha: .5,
                        barSpace: .5,
                        showLeds: false
                    }
                )
    
                // Init wavesurfer
                let wavesurfer = WaveSurfer.create({
                    container: '#waveform',
                    waveColor: '#A8DBA8',
                    progressColor: '#3B8686',
                    backend: 'MediaElement',
                    barWidth: 2,
                    barHeight: 1, // the height of the wave
                    barGap: null
                });
                // error console
                wavesurfer.on('error', function (e) {
                    console.warn(e);
                });
                // Load audio from URL
                wavesurfer.load('./Abba.mp3');
                // event button
                document.getElementById('playpause')
                    .addEventListener('click', () => {
                        wavesurfer.playPause();
                    })
            })
    
        </script>
    
    </body>
    
    </html>

  3. #3
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Cm se venisse caricato 2 volte lo script. Ovviamente funziona su browser che supporti html5. X quanto possa funzionare credo che sia inutile visualizzare un treno di impulsi, anche in media perdendo significativita, su uno schermo da 4k
    Per gli Spartani e Sparta usa spartan Il mio github

  4. #4
    Quote Originariamente inviata da ninja72 Visualizza il messaggio
    Esistono molte librerie gratuite per il tuo scopo, ti mando le prime due che ho trovato.
    Audiomotion-analyzer e Wavesurfer.

    codice:
    <!DOCTYPE html>
    <html lang="it-IT">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            canvas {
                width: 300px;
                height: 65px;
            }
    
            .audioblock {
                width: 300px;
            }
    
            #waveform {
                width: 300px;
            }
        </style>
    </head>
    
    <body>
    
        <div class="audioblock">
            <div id="container"></div>
            <audio src="Alpha.mp3" id="audio" controls crossorigin></audio>
        </div>
    
        <div id="waveform"></div>
        <button id="playpause">Play / Pause</button>
    
        <script src="https://unpkg.com/wavesurfer.js/dist/wavesurfer.js"></script>
      
      <script type="module">
            // load module from Skypack CDN
            import AudioMotionAnalyzer from 'https://cdn.skypack.dev/audiomotion-analyzer?min'
    
            window.addEventListener('DOMContentLoaded', () => {
                // audio source
                const audioEl = document.getElementById('audio')
    
                // instantiate analyzer
                const audioMotion = new AudioMotionAnalyzer(
                    document.getElementById('container'),
                    {
                        source: audioEl,
                        height: window.innerHeight - 50,
                        mode: 5,
                        gradient: 'prism', //classic / prism / rainbow
                        lineWidth: 2,
                        fillAlpha: .5,
                        barSpace: .5,
                        showLeds: false
                    }
                )
    
                // Init wavesurfer
                let wavesurfer = WaveSurfer.create({
                    container: '#waveform',
                    waveColor: '#A8DBA8',
                    progressColor: '#3B8686',
                    backend: 'MediaElement',
                    barWidth: 2,
                    barHeight: 1, // the height of the wave
                    barGap: null
                });
                // error console
                wavesurfer.on('error', function (e) {
                    console.warn(e);
                });
                // Load audio from URL
                wavesurfer.load('./Abba.mp3');
                // event button
                document.getElementById('playpause')
                    .addEventListener('click', () => {
                        wavesurfer.playPause();
                    })
            })
    
        </script>
    
    </body>
    
    </html>
    Wavesurcer.Js lo uso gia da un po di yempo ma mi fa un waveform solo e siccome io ho una lista di audio vorrei che ogni audio visualizzasse il suo waveform

  5. #5
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Su ff funziona benissimo.Qualche secondo di attesa
    Ultima modifica di linoma; 27-05-2021 a 10:34

  6. #6
    Quote Originariamente inviata da linoma Visualizza il messaggio
    Su ff funziona benissimo.Qualche secondo di attesa

    Quale quello che ho postato io?
    Perche lo provato su chrome e mi da quelli errori

  7. #7
    ok ora funziona anche a me avevo dimenticato d dichiarare AudioContext()

  8. #8
    Utente di HTML.it L'avatar di ninja72
    Registrato dal
    May 2020
    residenza
    -
    Messaggi
    319
    Wavesurcer.Js lo uso gia da un po di yempo ma mi fa un waveform solo e siccome io ho una lista di audio vorrei che ogni audio visualizzasse il suo waveform
    Wavesurfer-js permette di gestire le multi view anche se da codice custom, il discorso è vedere quale sia il miglior approccio per ciò che devi realizzare.
    Se devi caricare diversi brani dalla durata di svariati minuti, penso che la cosa migliore sia utilizzare un sistema playlist come mostrato nel loro esempio https://wavesurfer-js.org/example/playlist/index.html
    (tipo quello di beatport per capirci).

    Questo per non rallentare di molto il caricamento della pagina, diversamente potresti realizzare un funzione custom che prende un id e un url e ritorni un elemento DOM con relativi bottoni play / stop per esempio.

  9. #9
    Quote Originariamente inviata da ninja72 Visualizza il messaggio
    Wavesurfer-js permette di gestire le multi view anche se da codice custom, il discorso è vedere quale sia il miglior approccio per ciò che devi realizzare.
    Se devi caricare diversi brani dalla durata di svariati minuti, penso che la cosa migliore sia utilizzare un sistema playlist come mostrato nel loro esempio https://wavesurfer-js.org/example/playlist/index.html
    (tipo quello di beatport per capirci).

    Questo per non rallentare di molto il caricamento della pagina, diversamente potresti realizzare un funzione custom che prende un id e un url e ritorni un elemento DOM con relativi bottoni play / stop per esempio.
    Avevo gia visto la playlist di wavesurf ma non è quello che voglio fare io qui ce una playlist ma ce solo un waveform a me serve fare per ogni brano visualizzato il suo waveform tipo ad esempio come soundcloud.com che nella lista dei brani dell'artista ad ogni brano ce il rispettivo waveform ecco a me questo serve.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.