Does W3Schools play HTML5 audio tags?

Lyd på iOS: Fra HTML5-frustration til Web Audio API-succes

22/08/2024

Rating: 4.4 (3930 votes)

Hvis du nogensinde har forsøgt at bygge et webbaseret spil eller en app, der kræver lydeffekter, har du sandsynligvis oplevet frustrationen ved at få noget, der er trivielt at implementere i desktopbrowsere, til at fungere problemfrit på iOS-enheder. Den umiddelbare tanke er ofte at bruge HTML5-lydelementet, som på papiret ser ud til at have bred understøttelse. Men virkeligheden på iPhones og iPads er en helt anden, fyldt med uventede begrænsninger, der kan ødelægge din lydoplevelse og begrænse den interaktivitet, du ønsker at tilbyde dine brugere.

Does HTML5 support and tags?
HTML5-savvy browsers support and tags. Browsers that don’t support HTML5 ignore the tags and everything between the opening and closing tags except tags. To specify fallback behavior for older browsers, put the fallback HTML between the opening and closing or tags (after any tags).

HTML5-lyd og dens begrænsninger på iOS

HTML5 <audio>-elementet er designet til at gøre lydafspilning på nettet ligetil. Du kan simpelthen inkludere et <audio>-tag med en kilde og lade browseren håndtere resten:

<audio id="blast" src="blast.mp3"></audio>

Og så styre afspilningen med JavaScript:

var blasterTrigger = document.querySelector(".blasterTrigger"); blasterTrigger.addEventListener("click", function(){ document.getElementById("blast").play(); });

På de fleste desktopbrowsere fungerer dette fejlfrit, forudsat at du leverer et passende lydformat. Men så snart du tager din iPad eller iPhone frem, opdager du hurtigt, at tingene ikke er så enkle. Selvom Safari på iOS teknisk set understøtter <audio>-elementet, pålægger det nogle strenge restriktioner for afspilning. Disse begrænsninger er primært drevet af et ønske om at spare brugerens båndbredde og hukommelse, men nogle har også antydet, at Apple ønsker at holde medierige applikationer native og solgt via App Store.

De mest markante iOS-restriktioner kan opsummeres således:

  • Kun én lydkanal ad gangen: Dette er en af de mest frustrerende begrænsninger for spiludviklere. Du kan ikke have baggrundsmusik og lydeffekter, der afspilles samtidigt. Forsøger du at afspille flere lyde, vil du sandsynligvis kun høre én, eller den ene vil afbryde den anden. Dette forhindrer effektivt lagdeling eller overlappende lyde, hvilket er essentielt for en rig lydoplevelse i spil.
  • Ignorerer 'autoplay'-attributten: Din baggrundsmusik vil ikke starte automatisk, selvom du inkluderer autoplay-attributten i dit <audio>-tag. Lyden skal startes via en eksplicit brugerinteraktion.
  • Asynkron lydindlæsning forhindret: Lydspor kan ikke indlæses asynkront. De skal indlæses som en del af en UI-interaktion, såsom et klik eller en berøringshændelse. Lyde, der udløses i kode (og ikke er en del af en UI-interaktion), vil slet ikke afspilles. Dette gør det svært at forberede lyde i baggrunden, før de skal bruges.

Disse begrænsninger gør det utroligt udfordrende at skabe dynamiske og engagerende lydlandskaber på iOS ved brug af det almindelige HTML5 <audio>-element.

Tidligere forsøg på løsninger – og hvorfor de ikke var nok

Udviklere har gennem tiden forsøgt sig med forskellige metoder for at omgå begrænsningerne af <audio>-elementet på iOS, men ingen af dem har tilbudt en fuldkommen løsning.

Kø-systemer (Queueing)

En tilgang har været at bruge en enkelt lydkanal og sætte de ønskede spor i kø for at afspille dem sekventielt. Forestil dig en playliste, hvor kun én sang kan spille ad gangen:

<audio id="vivaldi" src="vivaldi.mp3"></audio> <button data-track="vivaldi">Afspil Vivaldi</button>

Med JavaScript ville man så administrere en kø, der afspiller næste spor, når det foregående er afsluttet. Selvom dette kan løse problemet med sekventiel afspilning, løser det ikke problemet med samtidig afspilning af flere lyde. Du kan stadig ikke have baggrundsmusik og lydeffekter på samme tid, og hvis du sætter spor i kø hurtigt efter hinanden, vil iOS nogle gange simpelthen ignorere operationen.

Audiosprites

En anden, mere avanceret tilgang er brugen af audiosprites – tænk CSS-sprites, men for lydfiler. Her kombinerer du alle dine lydeffekter til et enkelt lydspor, ofte adskilt af stilhed. For at afspille en bestemt lyd søger du blot til det specifikke tidspunkt i sporet og starter afspilningen.

Does Web Audio API support HTML5 audio?
The link refers to the Web Audio API, but the question refers to html5 audio elements. It's a viable workaround, but Web Audio API has a big downside by not allowing streaming of the sound file. It seems that you can set the muted property instead of updating the volume value.

Der findes værktøjer, der kan hjælpe med at skabe disse, f.eks. NPM-pakken audiosprite, som er en wrapper omkring FFmpeg. Den kan skabe dine sprites i mange formater og outputte en praktisk JSON-fil med timinginformation. Biblioteker som Zynga's Jukebox (som desværre er blevet fjernet fra GitHub) kunne tage disse JSON-filer og eksponere en praktisk API til afspilning af spor.

Selvom denne tilgang var en forbedring og overvandt flere af problemerne, var den stadig ikke perfekt. Du kunne stadig kun afspille ét spor ad gangen, og hurtige på hinanden følgende kø-kald kunne stadig føre til, at iOS forkastede operationen. Det var en kreativ løsning, men den adresserede ikke den fundamentale begrænsning af en enkelt lydkanal på iOS.

Web Audio API – Den ultimative løsning for iOS

Heldigvis findes der en anden, langt mere robust løsning: Web Audio API. Dette er en ny standard fra W3C, som har fundet vej til de fleste moderne browsere, herunder de seneste versioner af Firefox, Chrome og især Safari (inklusive iOS 6/7 og nyere). Det er et kraftfuldt JavaScript-interface, der er designet til sofistikeret lydsyntese og manipulation, og dets arkitektur er modelleret efter professionelle lydtekniske teknikker.

Web Audio API kan dog også bruges til at afspille en grundlæggende lydbuffer, herunder looping og stop af spor. Den lider (for nuværende) ikke af de samme begrænsninger som HTML5 <audio>-elementet, hvilket gør den til en yderst levedygtig kandidat for webbaserede spil med lydeffekter. Ved at bruge den på iOS omgår man den frustrerende enkeltkanalsbegrænsning, hvilket åbner op for en verden af muligheder for rige og dynamiske lydoplevelser.

Den underliggende API er optimeret på C++/Assembly-niveau, hvilket betyder, at den er ekstremt hurtig og har et lavt forbrug af hukommelse. Dette er afgørende for ydeevnen på mobile enheder.

Does Web Audio API support HTML5 audio?

Sådan fungerer Web Audio API (konceptuelt)

Kernen i Web Audio API er AudioContext. Forestil dig det som et lærred, hvor al din lydproduktion og manipulation finder sted. Du opretter typisk kun én AudioContext pr. side, som lever under hele applikationens levetid.

try { window.AudioContext = window.AudioContext || window.webkitAudioContext; window.audioContext = new window.AudioContext(); } catch (e) { console.log("Ingen Web Audio API understøttelse"); }

Indlæsning og buffering af lyd: Før du kan afspille en lyd, skal den indlæses og forberedes. Dette gøres typisk asynkront ved hjælp af XMLHttpRequest, hvor responsen forventes at være en arraybuffer. Denne binære lyddata afkodes derefter til en AudioBuffer ved hjælp af decodeAudioData-funktionen. Buffering betyder, at lyden er klar i hukommelsen til øjeblikkelig og gentagen afspilning, uden at skulle genindlæses fra serveren.

var request = new XMLHttpRequest(); request.open("GET", url, true); request.responseType = "arraybuffer"; request.onload = function () { self.context.decodeAudioData(request.response, function (buffer) { self.bufferList[url] = buffer; // Gem buffer til senere brug }); }; request.send();

Afspilning af lyd: Når lyden er bufferet, opretter du en AudioBufferSourceNode fra din AudioContext og tildeler den den indlæste AudioBuffer. For at lyden skal blive hørbar, skal du forbinde din kilde (source) til en destination, som typisk er din AudioContext's standardoutput (højttalere, hovedtelefoner osv.). Afspilningen startes med noteOn(0) (eller start(0) i nyere specifikationer), hvor 0 betyder "spil med det samme". Det er vigtigt at huske, at på iOS skal denne afspilning stadig udløses af en brugerinteraktion første gang for at omgå Apples autoplay-begrænsning for at "vække" lydkonteksten.

var source = this.manager.context.createBufferSource(); source.buffer = buffer; source.connect(this.manager.context.destination); // Forbinder kilde til output source.start(0); // Afspil med det samme

Routing og mixing af lyde: En af de mest kraftfulde funktioner i Web Audio API er muligheden for at indsætte et komplekst graf af lydnoder mellem din lydkilde og destination. Dette koncept ligner en guitarists pedalbræt. Du kan sende din rå lyd gennem forskellige filtre og effekter, før lyden afspilles som hørbar output. Dette giver dig finere kontrol til at transformere din lyd.

Eksempler på noder inkluderer:

  • GainNode: Til at styre lydstyrken.
  • DynamicsCompressorNode: Til at normalisere lydstyrken, så der ikke er ekstremt stille eller høje dele.
  • BiquadFilterNode: Til at anvende filtre som highpass, lowpass, bandpass osv.
  • PannerNode: Til at placere lyden i et 3D-rum.

Du kan forbinde disse noder i kæder:

source.connect(compressor); compressor.connect(reverb); reverb.connect(volume); volume.connect(myAudioContext.destination);

Dette giver dig utrolig fleksibilitet til at designe din lyd. Du kan også mikse flere kilder sammen til at afspille ud af den samme destination, hvilket er nyttigt for f.eks. crossfading mellem to spor eller at have flere lydeffekter afspillet samtidigt.

How to stream audio in HTML5?
In Audio and Video HTML, you learned how to stream audio using the HTML5 element. While the tag is suitable for basic needs such as streaming and media playback, another option called the Web Audio API offers a more comprehensive audio-based toolkit. The Web Audio API is a JavaScript interface that features the ability to:

Syntetisering af lyd: Ud over at afspille forudindlæste lydfiler kan du også generere lyde direkte med OscillatorNode. Dette er fantastisk til at skabe biplyde, simple toner eller endda mere komplekse syntetiserede lyde ved at definere forskellige bølgeformer (sinus, firkant, savtand, trekant).

Visualisering af lyd: Med AnalyserNode kan du få adgang til rå lyddata i realtid. Dette åbner op for spændende muligheder for at visualisere lyden, f.eks. ved at tegne et lydspektrum på et HTML5 canvas, som vist i nogle avancerede eksempler.

Samlet set giver Web Audio API dig den kontrol og fleksibilitet, der er nødvendig for at skabe rige, interaktive og højtydende lydoplevelser på tværs af alle enheder, inklusive de udfordrende iOS-platforme. Det er det foretrukne valg for seriøs weblyd.

Sammenligning: HTML5 <audio> vs. Web Audio API på iOS

For at opsummere de vigtigste forskelle og fordele ved Web Audio API, især i konteksten af iOS, kan vi se på følgende tabel:

FunktionHTML5 <audio> på iOSWeb Audio API på iOS
Samtidig afspilningNej (kun 1 kanal ad gangen)Ja (flere kanaler og lydeffekter samtidigt)
AutoplayIgnoreres (kræver brugerinteraktion)Fungerer efter en indledende brugerinitiering (til at "vække" lydkonteksten)
Volumenkontrol via JavaScriptNej (lydstyrken er under brugerens fysiske kontrol)Ja (fuld kontrol via GainNode)
Præcis timing af lydeSvært og upålideligtMeget præcist (kan planlægge lyde ned til millisekunder)
Lydmanipulation & effekterMeget begrænset (grundlæggende afspilning, pause, stop)Avanceret (filtre, rumklang, kompression, panning, syntese m.m.)
HukommelsesforbrugVariabelt, kan være ineffektivt ved mange <audio>-elementerOptimeret og lavt, især ved genbrug af buffere
Kompleksitet at implementereSimpelt for grundlæggende afspilningHøjere kompleksitet, men giver langt mere kontrol

Ofte Stillede Spørgsmål (FAQ)

Her er svar på nogle af de mest almindelige spørgsmål vedrørende lyd på iOS og Web Audio API:

Hvorfor virker 'autoplay' ikke på iOS med HTML5 audio?
iOS-enheder ignorerer autoplay-attributten for HTML5 <audio> og <video> elementer. Dette er en bevidst beslutning fra Apple for at spare brugerens mobildata og forhindre uønsket lyd i at afspille automatisk, hvilket kan være forstyrrende. Lyd skal altid udløses af en eksplicit brugerhandling (f.eks. et tryk på en knap) på iOS.

Kan jeg styre lydstyrken af HTML5 audio på iOS via JavaScript?
Nej, desværre ikke med det almindelige HTML5 <audio>-element. På iOS-enheder er lydstyrken altid under brugerens fysiske kontrol (via volumenknapperne på enheden). JavaScript kan ikke indstille volume-egenskaben, og læsning af den vil altid returnere 1 (fuld lydstyrke), uanset den faktiske enhedsvolumen. Web Audio API omgår dog denne begrænsning og giver dig fuld programmatisk kontrol over lydstyrken via GainNode.

What browsers do you use to play HTML5 games?
This story starts when we had to provide audio to an HTML5 game we were building. The game is for mobile browsers, actually a limited and updated range of mobile browsers: Safari for iOS 6+, and the stock browser (i.e. the default browser) for Android 4+.

Hvad er hovedforskellen mellem HTML5 audio og Web Audio API?
HTML5 <audio> er designet til simpel medieafspilning – tænk en grundlæggende musikafspiller eller videoafspiller. Det er let at implementere, men tilbyder begrænset kontrol. Web Audio API er derimod et lavniveau JavaScript-API designet til avanceret lydsyntese, manipulation og analyse. Det giver dig granular kontrol over lydstrømmen, herunder mulighed for at tilføje effekter, mikse flere lyde og opnå præcis timing, hvilket gør det ideelt til spil og interaktive lydapplikationer, især hvor HTML5 <audio> kommer til kort (som på iOS).

Er Web Audio API svær at lære?
Web Audio API er mere kompleks end det simple HTML5 <audio>-tag, da det involverer koncepter som AudioContext, lydnoder og grafer. Det kræver en dybere forståelse af lydbehandling. Dog er de grundlæggende principper for indlæsning og afspilning af lyde relativt ligetil, og der findes mange ressourcer og eksempler online, der kan hjælpe dig i gang. For simple spil med lydeffekter er kompleksiteten ofte det værd for den øgede funktionalitet og kompatibilitet, især på iOS.

Hvad bruges Web Audio API typisk til?
Web Audio API bruges til en bred vifte af applikationer ud over blot at omgå iOS-begrænsninger. Typiske anvendelser inkluderer:

  • Lydeffekter i webbaserede spil.
  • Musikafspillere med avancerede funktioner (f.eks. DJ-apps med crossfading, visualisering).
  • Lydredigeringsværktøjer i browseren.
  • Syntetisatorer og musikinstrumenter, der genererer lyd dynamisk.
  • Talebehandling og lydeffekter i realtid.

Kort sagt, hvor som helst du har brug for mere end blot grundlæggende afspilning af en lydfil, er Web Audio API det rigtige valg.

Samlet set, selvom HTML5 <audio>-elementet er en god start for simple lydbehov på tværs af mange platforme, falder det desværre igennem, når det kommer til de specifikke begrænsninger på iOS. Web Audio API træder ind som den robuste og fleksible løsning, der giver udviklere magten til at skabe rige, flerlagede og interaktive lydoplevelser, der fungerer problemfrit på iPhones og iPads. Ved at investere tid i at forstå og implementere Web Audio API kan du overvinde de mest frustrerende lydudfordringer på mobile enheder og give dine brugere en overlegen oplevelse. Det er den uundværlige standard for sofistikeret weblyd.

Hvis du vil læse andre artikler, der ligner Lyd på iOS: Fra HTML5-frustration til Web Audio API-succes, kan du besøge kategorien Teknologi.

Go up