Integrationsguide
Sæt en afspiller på dit websted
Lad besøgende lytte uden at forlade webstedet. Opret en lydafspiller i Obbo, indsæt koden på siden, og du er klar. Send guiden til den, der vedligeholder dit websted.
De første tre trin er nok for de fleste websteder. Styling og udviklerreference er valgfrit.
01Hent et afspiller-id
En afspiller er det, du indlejrer. Den peger på en hel podcast eller på bestemte afsnit, og den har et offentligt id, du indsætter i din HTML.
- Åbn Konto og derefter Lydafspillere.
- Opret en afspiller, giv den et navn til dit eget brug, og tilføj det, den skal spille: en hel podcast, ét afsnit eller flere afsnit i den rækkefølge, du vælger.
- Kopiér afspiller-id'et.
- Udgiv ændringerne, og hold afspilleren aktiveret. Besøgende ser ikke kladder.
Id'et er ment til at være offentligt.Det står i din sides kildekode, hvor alle kan læse det, og det er fint. Det giver én ting: adgang til at afspille de afsnit, du lagde i den afspiller. Det er ikke en API-nøgle, det når intet andet på din konto, og deaktiverer du afspilleren, tilbagekaldes det alle steder på én gang.
Nye færdige afsnit vises automatisk, når afspilleren omfatter hele podcasten. Ændrer du de valgte afsnit eller indstillinger, skal ændringerne udgives. Indlejringskoden skal ikke udskiftes.
02Indsæt to linjer
Erstat YOUR_WIDGET_ID med dit afspiller-id. Sæt scriptet på siden og div'en dér, hvor afspilleren skal vises. I en hjemmesidebygger skal du bruge en HTML- eller indlejringsblok, der tillader scripts.
<script src="https://www.obbo.me/player/obboplayer.js" async></script>
<div data-obbo-player="YOUR_WIDGET_ID"></div>Det er en komplet integration. Scriptet finder hvert element med attributten data-obbo-player og udfylder det, uanset om siden har én afspiller eller ti. Det gør ingen skade at indlæse scriptet to gange.
Lyd hentes først, når nogen trykker afspil.Afsnitsliste og cover hentes sammen med siden, men lyd hentes først, når en besøgende starter afspilningen. En sidevisning tæller ikke som en afspilning.
03Tjek din udgivne side
Gem og udgiv webstedet, og åbn siden som besøgende. Nogle redigeringsværktøjer kører ikke scripts i deres forhåndsvisning.
- Podcasttitlen og færdige afsnit skal vises uden login til Obbo.
- Tryk afspil, prøv søgebjælken, og sæt på pause. Lyden skal først starte, når du beder om det.
- Tjek siden på både telefon og en bredere skærm. Mangler afspilleren, så kontrollér, at værktøjet tillader tilpasset HTML og eksterne scripts.
Du er klar.Du kan stoppe her. Læs kun videre, hvis du ønsker et andet layout, dit eget udtryk eller en særlig integration.
04Vælg et layout
Der er seks synlige layouts samt auto. Vælg med data-obbo-ui. Udelad det, eller brug auto for at følge afspillerens udgivne kompakt- eller listeindstilling.
Tilbage til afspillernes prøveside
| Værdi | Hvad det er |
|---|---|
list | Knapperne med din afsnitsliste under. Til en hel podcast, eller når nogen kunne tænkes at ville et andet afsnit end det nyeste. |
bar | Kun knapperne. Til en artikel eller produktside bygget op om ét afsnit. |
card | Coveret i fuld størrelse med knappen på kanten. Til sidebjælker og gitre, hvor en vandret bjælke ser påklistret ud. |
inline | En afspilningsknap og et ur i en størrelse, der passer ind i en sætning frem for at afbryde den. |
dock | Sætter sig fast i bunden af vinduet, når nogen trykker afspil, så knapperne ikke forsvinder, når man ruller. Kan lukkes. |
transcript | Afsnittet som læsbar tekst, der følger lyden. Den linje, der bliver sagt, fremhæves; klik på en linje for at springe dertil. |
auto | Standarden. Følger det layout, der er gemt på afspilleren. |
<script src="https://www.obbo.me/player/obboplayer.js" async></script>
<div
data-obbo-player="YOUR_WIDGET_ID"
data-obbo-ui="list"
data-obbo-theme="dark"
></div>Alle attributter
| Indstilling eller identifikator | Hvad den gør |
|---|---|
data-obbo-player | Påkrævet. Dit afspiller-id. |
data-obbo-ui | list, bar, card, inline, dock, transcript eller auto. |
data-obbo-theme | light eller dark. |
data-obbo-episode | Start på et bestemt afsnit. Det bliver valgt, ikke afspillet. |
data-obbo-isolate | Vis inde i en shadow root, adskilt fra din CSS. |
data-obbo-locale | Sprog for afspillerens egne knapper: en, es, da eller ja. Afsnitstitler kommer fra din podcast under alle omstændigheder. |
data-obbo-language | Lydsprog: en, es, da, ja, de, fr, it, nl, sv, no eller pl. Bruger som standard sidens lang-attribut. Findes sproget ikke, afspilles originaloptagelsen. |
data-obbo-autoadvance | Spil næste afsnit, når et slutter. |
Flere afspillere på én side er fint.De deler én enkelt forespørgsel efter din afsnitsliste, og starter man én, sættes de andre på pause, så en besøgende aldrig ender med to stemmer på én gang.
05Få den til at ligne dit websted
Afspilleren vises på din side, ikke i en iframe. Brug variablerne til farver, hjørner og skrifttype. Eksemplet indeholder klassen, der forbinder HTML og CSS.
Den hurtige måde: ni variabler
| CSS-variabel | Standardværdi |
|---|---|
--obbo-player-bg | #ffffff |
--obbo-player-fg | #1c2733 |
--obbo-player-muted | #66768a |
--obbo-player-accent | #2f6fed |
--obbo-player-accent-fg | #ffffff |
--obbo-player-border | #e3e8ef |
--obbo-player-row-hover | #f4f6f9 |
--obbo-player-radius | 12px |
--obbo-player-font | Systemets skrifttyper |
<div class="my-player" data-obbo-player="YOUR_WIDGET_ID"></div>
<style>
.my-player {
--obbo-player-accent: #a1482e;
--obbo-player-radius: 8px;
--obbo-player-font: system-ui, sans-serif;
}
</style>Den grundige måde: klassenavne
Faste obbo--klasser giver adgang til knapperne. Brug helst variabler til dit udtryk og klasser til detaljer. data-obbo-state bruges til indlæsnings- og fejltilstande. Behold fejlbeskeder synlige, så besøgende ved, når afspilning ikke er mulig.
| Indstilling eller identifikator | Hvad den gør |
|---|---|
.obbo-p | Afspillerens rod. Har data-obbo-state. |
.obbo-play | Afspil- og pauseknap. |
.obbo-seek | Søgebjælken, et input af typen range. |
.obbo-title / .obbo-sub | Afsnitstitel og podcastnavn. |
.obbo-art | Coverbillede. Skjules, hvis podcasten ikke har et. |
.obbo-list / .obbo-row | Afsnitsliste og dens rækker. Den spillende række har aria-current. |
.obbo-note | Beskeden ved indlæsning, tom og fejl. |
.obbo-p[data-obbo-state="loading"] { opacity: 0.6; }
.obbo-p[data-obbo-state="error"] .obbo-note { font-weight: 700; }Er din CSS aggressiv, så luk den ude.Tilføj data-obbo-isolate til et layout på siden for at beskytte det mod din CSS. De ni variabler virker stadig, men klasser når ikke ind. Dock-layoutet sættes på dokumentet og understøtter ikke shadow-isolation.
06Byg din egen afspiller
Spring layoutene helt over. createPlayer giver dig afsnitsdata, afspilning og position; du skriver markuppet. Lytning bliver stadig talt med, og udløbne lydlinks henter sig stadig, uden at nogen af delene er dit problem. Knapperne herunder kører koden, der står nedenunder.
Levende eksempel fra Momento. Knapperne bruger samme afspilningsmotor som de færdige layouts.
Indlæser eksemplet…
<script src="https://www.obbo.me/player/obboplayer.js" async></script>
<button id="play" type="button" disabled>Play</button>
<span id="time">0:00</span>
<script>
addEventListener('load', function () {
var player = Obbo.createPlayer({ widgetId: 'YOUR_WIDGET_ID' });
var button = document.getElementById('play');
var time = document.getElementById('time');
player.subscribe(function (state) {
button.disabled = state.status !== 'ready' || !state.playable;
button.textContent = state.playing ? 'Pause' : 'Play';
time.textContent = Obbo.formatTime(state.position);
});
button.onclick = function () { player.toggle(); };
});
</script>Hold knappen deaktiveret, indtil status er ready.På iOS er tilladelsen til at afspille lyd bundet til det tryk, der bad om den. Et tryk, afspilleren endnu ikke kan handle på, er spildt, og din besøgende skal trykke igen.
07Udskriften, der følger med
Udskriftslayoutet lægger hele afsnittet på din side som tekst og holder det i takt med lyden. Hvert Obbo-afsnit bliver skrevet ud med tidsmarkering pr. sætning som en del af produktionen, så du skal ikke forberede noget.
- Den linje, der bliver sagt, fremhæves og ruller sig selv frem. Ruller du selv, holder den op med at følge med, og en knap fører dig tilbage — den slås ikke med dig om rullebjælken.
- Klikker man på en linje, spilles der derfra, og det gør afsnittet citerbart: en læser kan finde den sætning, de vil have, og høre den sagt.
- Udskriften kan markeres og læses af hjælpeteknologi efter indlæsning. Behold vigtig tekst i sidens egen HTML, når søgesynlighed betyder noget; JavaScript-genereret tekst bliver ikke nødvendigvis indekseret.
<script src="https://www.obbo.me/player/obboplayer.js" async></script>
<div data-obbo-player="YOUR_WIDGET_ID" data-obbo-ui="transcript"></div>Bruger den tilgængelige udskrift for hvert afsnit.Færdige udskrifter leveres af indlejrings-API'et. Mangler en udskrift, virker lyden stadig, og afspilleren forklarer det. Prøvesiden har et fungerende læs-med-eksempel.
08API-reference
Obbo.createPlayer(options)
| Indstilling eller identifikator | Hvad den gør |
|---|---|
widgetId | Påkrævet. Dit afspiller-id. |
locale | Sprog for indbyggede etiketter. Standard er en. |
language | Det ønskede lydsprog. Brug sidens sprog; manglende sprogversioner afspilles som originaloptagelsen. |
apiBase | Den offentlige API-adresse. Standard er https://app.obbo.me. Skift kun ved brug af en anden Obbo-server. |
autoAdvance | Fortsæt til næste afsnit. Slået fra som standard. |
exclusive | Sæt andre afspillere på siden på pause, når denne starter. Slået til som standard. |
Afspilleren
| Indstilling eller identifikator | Hvad den gør |
|---|---|
subscribe(fn) | Kalder din funktion med hele tilstanden ved hver ændring, og én gang med det samme. Returnerer en funktion, der afmelder. |
getState() | Den aktuelle tilstand, hvis du hellere vil hente end abonnere. |
play(episodeId?) | Begynd at afspille, eventuelt med et skift af afsnit først. |
pause() / toggle() | Det indlysende. |
select(episodeId) | Skift afsnit uden at afspille. Koster ingen forespørgsel. |
seek(seconds) | Spring til en position, i sekunder. |
setRate(rate) | Afspilningshastighed, fra 0,75 til 2. |
next() / previous() | Bevæg dig gennem afsnitslisten. |
reload() | Hent afsnitslisten igen. |
destroy() | Stop og kobl fra. Kald den, når din komponent fjernes. |
media | Det underliggende lydelement, til noget vi ikke har tænkt på. |
Tilstanden
| Indstilling eller identifikator | Hvad den gør |
|---|---|
status | loading, ready, empty eller error. |
error | Tom, eller blocked når browseren nægtede uden et tryk, load_failed, eller unavailable ved et forkert eller tilbagekaldt id. |
episodes | Alle afsnit i afspilleren: titel, beskrivelse, nummer, dato og længde. |
episode | Det valgte. Valgt betyder ikke, at det spiller. |
podcast | Titel, firmanavn og coverbillede. |
playing | Om der spiller lyd lige nu. |
position / duration | Begge i sekunder. |
playable | Om det valgte afsnit overhovedet kan afspilles. |
Også på Obbo
| Indstilling eller identifikator | Hvad den gør |
|---|---|
Obbo.formatTime(s) | Laver 65 om til 1:05, ligesom de indbyggede layouts gør. |
Obbo.ui.list(el, player, opts) | Montér selv et indbygget layout. Returnerer et objekt med destroy. |
Obbo.mount(root?) | Find afspillerelementer og montér dem. Kald den, hvis du tilføjer markup dynamisk. |
Obbo.unmountElement(el) | Fjern én. |
Obbo.version | Værd at oplyse i en fejlrapport. |
09React, Vue og resten
Stol ikke på den automatiske scanning. Et framework, der gentegner beholderen, sletter afspillerens markup og efterlader dens event-lyttere. Montér den selv, og fjern den ved unmount, i et element du aldrig selv tegner i.
import { useEffect, useRef, useState } from 'react';
let sdkPromise;
function loadPlayer() {
if (window.Obbo) return Promise.resolve(window.Obbo);
if (sdkPromise) return sdkPromise;
sdkPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = 'https://www.obbo.me/player/obboplayer.js';
script.async = true;
script.onload = () => {
if (window.Obbo) resolve(window.Obbo);
else {
sdkPromise = null;
script.remove();
reject(new Error('Player SDK unavailable'));
}
};
script.onerror = () => {
sdkPromise = null;
script.remove();
reject(new Error('Player SDK could not load'));
};
document.head.appendChild(script);
});
return sdkPromise;
}
export function Player({ widgetId, locale = 'en' }) {
const host = useRef(null);
const [failed, setFailed] = useState(false);
const [attempt, setAttempt] = useState(0);
useEffect(() => {
let cancelled = false;
let cleanup;
loadPlayer().then((Obbo) => {
if (cancelled) return;
const player = Obbo.createPlayer({ widgetId, locale, language: locale });
const ui = Obbo.ui.list(host.current, player, { locale });
cleanup = () => { ui.destroy(); player.destroy(); };
}).catch((error) => {
if (!cancelled) {
console.error('Player failed to load', error);
setFailed(true);
}
});
return () => { cancelled = true; cleanup?.(); };
}, [widgetId, locale, attempt]);
return <>
<div ref={host} />
{failed && <p role="alert">
The player could not load.
<button type="button" onClick={() => {
setFailed(false);
setAttempt((value) => value + 1);
}}>Try again</button>
</p>}
</>;
}Eksemplet venter på SDK'et, aflyser sene monteringer og fjerner både layout og afspiller ved oprydning. Giv sidens sprog som locale. Brug samme livscyklus i Vue eller Svelte. Inline-eksempler kan kræve en CSP-nonce eller en ekstern JavaScript-fil efter sidens politik.
10Content-Security-Policy
Sender siden Content-Security-Policy, så gennemgå direktiverne med udvikleren. Tilføj værterne til den eksisterende politik; rækkerne er ikke en komplet politik til indsætning.
| Indstilling eller identifikator | Hvad den gør |
|---|---|
script-src https://www.obbo.me | For at indlæse afspilleren. |
connect-src https://app.obbo.me | For at hente din afsnitsliste. |
media-src https://app.obbo.me https://*.amazonaws.com | For at streame selve lyden. |
style-src | SDK'et indsætter et inline-stylesheet. Politikken skal tillade det; bundlen understøtter ikke en stylesheet-nonce. Gennemgå kravet med udvikleren i stedet for at slå CSP fra. |
img-src | Tillad værten for podcastens cover, ofte S3. Brug den faktiske billedadresse til at begrænse listen over tilladte værter. |
media-src er den, folk glemmer.Lyd leveres fra lagring på en anden vært end API'et. Udelader du den, ser afspilleren helt rask ud, lige indtil nogen trykker afspil.
11Hvad der tælles
Lytning på dit websted dukker op i din Obbo-statistik: hvor mange gange afspilleren blev indlæst, hvor mange afspilninger der startede, og hvor meget der faktisk blev hørt.
- Dine besøgende bliver aldrig identificeret. Ingen konto, intet login, og afspilleren sætter ingen cookie. Rapporter tilskrives dig som ejer, ikke den, der lytter.
- Et sidevisning er ikke en afspilning. Intet tæller som afspilning, før lyden rent faktisk starter.
- Lyttetid måles, den antages ikke. At spole frem tæller ikke som at have hørt det, du sprang over.
12Når det ikke virker
Der kommer slet ikke noget frem
Tjek, at elementet har data-obbo-player med dit id, og at script-tagget er på siden. Tilføjede du markuppet, efter siden var indlæst, så kald Obbo.mount() én gang bagefter.
Der står, at afspilleren ikke er tilgængelig
Id'et er forkert, eller afspilleren er deaktiveret på din konto. Begge dele giver med vilje den samme besked.
Der står, at der ingen afsnit er
Afspilleren er tom, eller dens afsnit er stadig under produktion. Kun færdige afsnit leveres.
Den ser rigtig ud, men vil ikke spille
Næsten altid manglende media-src i din Content-Security-Policy. Ellers tjek state.error: blocked betyder, at browseren først ville have et rigtigt tryk, hvilket sker, når afspilning udløses af noget andet end et klik.
Den ser forkert ud
Din sides CSS når ind i den, hvilket som regel er meningen, men af og til ikke er. Tilføj data-obbo-isolate for at lukke den ude.
Stadig i tvivl?Send os sidens adresse, dit afspiller-id og værdien af Obbo.version på hello@obbo.me