# DataFirefly Native Live Shopping: documentatie

> Overzicht DataFirefly Native Live Shopping maakt van uw WooCommerce-winkel een zelfstandig live shopping-platform, zonder afhankelijkheid van een externe dienst als Bambuser of CommentSold. De uitzending gebruikt WebRTC peer-to-peer mesh vanuit…

- Pagina: <https://www.datafirefly.com/nl/documentation/dfnativeliveshopping/>
- Taal: nl
- Bijgewerkt op: 2026-08-19
- Andere talen: [fr](https://www.datafirefly.com/documentation/dfnativeliveshopping/index.md), [en](https://www.datafirefly.com/en/documentation/dfnativeliveshopping/index.md), [es](https://www.datafirefly.com/es/documentation/dfnativeliveshopping/index.md), [de](https://www.datafirefly.com/de/documentation/dfnativeliveshopping/index.md), [it](https://www.datafirefly.com/it/documentation/dfnativeliveshopping/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfnativeliveshopping/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfnativeliveshopping/index.md)
- Index: <https://www.datafirefly.com/nl/documentation/llms.txt>

## Overzicht

DataFirefly Native Live Shopping maakt van uw WooCommerce-winkel een zelfstandig live shopping-platform, zonder afhankelijkheid van een externe dienst als Bambuser of CommentSold. De uitzending gebruikt **WebRTC peer-to-peer mesh** vanuit de browser van de presentator naar elke kijker, de signalering verloopt via de WordPress REST API, en de replay wordt aan de clientzijde opgenomen met de MediaRecorder-API en daarna als WordPress-bijlagen opgeslagen.

De plugin biedt:

- een CPT `dfnls_live_show` om uw uitzendingen aan te maken en in te plannen;
- een presentatorconsole die in het WordPress-beheer is ingebouwd (camerapreview, bediening, producten, chat);
- een kant-en-klare kijkerservaring met aanklikbare producten in overlay en een chat;
- een brug naar de WooCommerce-winkelwagen (officieel toevoegen aan de winkelwagen zonder de uitzending te verlaten);
- een automatische replay die synchroon loopt met de gebeurtenissen van de uitzending (spotlights, coupons, berichten);
- een eigen Gutenberg-blok en de shortcode `[dfnls_live]`.

**Architectuur**: de WebRTC-meshtopologie is ideaal tot ongeveer 25 gelijktijdige kijkers per presentator. Daarboven voorziet u beter een externe TURN-server, of overweegt u een SFU. De uploadbandbreedte van de presentator moet ongeveer 500 kbps per verbonden kijker bedragen.

## Vereisten

- **WordPress** 6.3 of hoger
- **WooCommerce** 8.0 of hoger (compatibel met HPOS)
- **PHP** 8.1 of hoger (getest tot 8.3)
- **HTTPS verplicht**: `getUserMedia()` en `getDisplayMedia()` weigeren te werken over onbeveiligde HTTP
- Ondersteunde browsers aan kijkerszijde: Chrome 80+, Firefox 75+, Edge 80+, Safari 14+, Opera 67+
- Een recente browser aan presentatorzijde, met toegang tot camera en microfoon

**Belangrijk**: zonder geldige HTTPS (Let's Encrypt volstaat) krijgt de presentatorconsole geen toegang tot de camera en de microfoon. Test op `localhost` of op een domein met een TLS-certificaat.

## Installatie

1. Download het archief `df-native-live-shopping.zip` vanuit uw DataFirefly-account.
2. Ga in WordPress naar _Plugins → Nieuwe plugin_ en daarna _Plugin uploaden_.
3. Selecteer het ZIP-bestand en klik op _Nu installeren_.
4. Klik na de installatie op _Plugin activeren_.
5. Er verschijnt een nieuw menu **Live Shopping** in de beheerzijbalk.

Bij de activering doet de plugin het volgende:

- ze maakt 5 eigen tabellen aan (`wp_dfnls_signaling`, `_sessions`, `_events`, `_replay_parts`, `_chat`);
- ze voegt de capabilities `manage_dfnls_lives` en `host_dfnls_lives` toe aan de rollen `administrator` en `shop_manager`;
- ze plant twee crons in: een dagelijkse opruiming van oude replays en een uurlijkse opruiming van verouderde signaleringsberichten;
- ze legt de standaardopties vast (STUN-servers van Google, 90 dagen bewaartermijn, maximaal 25 kijkers en zo verder).

## Uw eerste uitzending in 5 minuten

De kortste weg naar uw eerste uitzending:

1. Menu **Live Shopping → Nieuwe uitzending**.
2. Vul een titel in (bijvoorbeeld "Voorjaarsdeals").
3. Zoek en selecteer in de metabox _Producten_ de WooCommerce-producten die u wilt tonen (met slepen en neerzetten wijzigt u de volgorde).
4. Optioneel: leg bij _Planning_ een startdatum en -tijd vast (kijkers zien dan een aftelklok).
5. Publiceer de uitzending.
6. Ga naar **Live Shopping → Presentatorconsole** en kies uw uitzending.
7. Klik op _Uitzending starten_ en geef toestemming voor camera en microfoon.
8. Deel de publieke URL van de uitzending (`/live/uw-slug/`) met uw publiek.

## Presentatorconsole

De presentatorconsole is het dashboard van waaruit u uw uitzending leidt. U bereikt die via _Live Shopping → Presentatorconsole_. De functies:

### Videopreview en bediening

- **Camera**: schakelaar om de camera aan of uit te zetten
- **Microfoon**: schakelaar om de microfoon aan of uit te zetten
- **Scherm delen**: vervangt de camerastream door een gedeeld scherm (handig voor demonstraties)
- **Starten en stoppen**: de hoofdknoppen voor de uitzending

### Producten uitlichten

De lijst met producten die aan de uitzending zijn gekoppeld, staat rechts. Elk product heeft een knop _Uitlichten_. Daarop klikken:

- toont het product meteen in overlay bij alle kijkers;
- legt een gebeurtenis `product.spotlight` met tijdstempel vast, voor de synchronisatie van de replay;
- een tweede klik op dezelfde knop haalt de overlay weg.

### Coupons uitsturen

Vul een kortingscode in (bijvoorbeeld `LIVE20`) en eventueel een omschrijving, en klik daarna op _Uitsturen_. Bij de kijkers verschijnt een geanimeerde flits met een knop "Kopiëren" om de code met één klik over te nemen.

### Presentatorberichten

Met een vrij invoerveld verstuurt u een bericht dat bij de kijkers als tijdelijke banner verschijnt (standaard 8 seconden).

### Livechat

De chat tussen presentator en kijkers zit in de console ingebouwd. De berichten van de presentator zijn in alle weergaven visueel te onderscheiden (badge en rode rand).

### Activiteitenlogboek

Onder in de console toont een logboek in realtime de verbindingen en verbrekingen, de uitgestuurde gebeurtenissen, de geüploade replaychunks en eventuele fouten.

## Kijkersweergave

Wat uw publiek ziet zodra het op de publieke URL van de uitzending komt:

- **Vóór de uitzending**: is de uitzending ingepland, dan verschijnt een wachtscherm met een aftelklok tot het geplande tijdstip. De status wordt elke 5 seconden opgevraagd om de start te herkennen.
- **Tijdens de uitzending**: live video met een pulserend "LIVE"-bolletje en een kijkersteller. In de zijbalk staan twee tabbladen: _Producten_ (de aanklikbare lijst met producten uit de uitzending) en _Chat_.
- **Productoverlay**: licht de presentator een product uit, dan schuift er een kaart in beeld (standaard rechtsonder) met foto, naam, prijs en de knop _Toevoegen aan winkelwagen_.
- **Toevoegen aan de winkelwagen**: met een klik op de knop komt het product in de officiële WooCommerce-winkelwagen. Rechtsonder verschijnt een zwevende knop met de teller van het aantal artikelen.
- **Flitscoupon**: door de presentator uitgestuurd, verschijnt bovenaan met animatie en een kopieerknop.
- **Na de uitzending**: is de replay ingeschakeld, dan kunnen kijkers via een knop "Replay bekijken" de uitzending opnieuw afspelen, met volledige synchronisatie van de gebeurtenissen.

## Algemene instellingen

Menu **Live Shopping → Instellingen**. De belangrijkste onderdelen:

### STUN-servers

Standaard worden de publieke STUN-servers van Google gebruikt:

```
stun:stun.l.google.com:19302
stun:stun1.l.google.com:19302
```

U kunt uw eigen STUN-servers toevoegen (één per regel).

### TURN-servers

Optioneel, maar aan te raden voor kijkers achter symmetrische NAT (sommige 4G-providers, bedrijfs-VPN's). Formaat:

```
turn:turn.voorbeeld.com:3478
turns:turn.voorbeeld.com:5349
```

Vul de bijbehorende _TURN username_ en _TURN credential_ in.

### Opname en replay

- **Opname ingeschakeld**: algemeen aan of uit
- **Duur van de chunks** (ms): standaard 5000. Korter betekent beter bestand tegen een crash maar meer verzoeken; langer betekent minder verzoeken maar meer verlies bij een crash
- **Bewaartermijn van de replays** (dagen): standaard 90. Daarna verwijdert de dagelijkse cron automatisch de WebM-bestanden en de bijbehorende regels

### Capaciteit en overlay

- **Maximaal aantal kijkers per presentator**: standaard 25. Pas dit aan uw uploadbandbreedte aan
- **Positie van de overlay**: rechts, links of onderaan

### Standaardwaarden per uitzending

- Chat standaard ingeschakeld
- Replay standaard ingeschakeld
- Inloggen standaard vereist

## STUN en TURN: wanneer een TURN instellen

STUN is een eenvoudige server om het publieke IP-adres te ontdekken, gratis en in ongeveer 85 procent van de gevallen voldoende. TURN daarentegen relayt het mediaverkeer echt: dat kost bandbreedte, maar maakt het mogelijk twee clients te verbinden die elkaar niet rechtstreeks kunnen bereiken.

Stel een TURN in als:

- uw kijkers regelmatig melden dat ze de video niet zien (de WebRTC-verbinding blijft hangen op "connecting");
- uw publiek veel mobiele gebruikers op 4G of 5G telt bij providers met symmetrische NAT;
- uw presentator of uw kijkers achter een strikt bedrijfs-VPN zitten.

**Aanbevolen oplossing**: een zelfgehoste [coturn](https://github.com/coturn/coturn) op een kleine VPS (5 tot 10 euro per maand) volstaat voor 30 tot 40 gelijktijdige kijkers. Betalende alternatieven: Xirsys of Twilio Network Traversal Service.

## Opname en replay

### Hoe de opname werkt

De opname gebeurt volledig **in de browser van de presentator**, via de MediaRecorder-API:

1. Bij de start van de uitzending wordt MediaRecorder aangemaakt, met automatische herkenning van de beste beschikbare codec (VP9 boven VP8 boven H.264, opus voor audio, ongeveer 1,5 Mbps video plus 96 kbps audio).
2. Elke 5 seconden (instelbaar) wordt een WebM-chunk aangemaakt en geüpload via `POST /wp-json/df-nls/v1/shows/{id}/replay/chunk`.
3. De chunk wordt als WordPress-bijlage opgeslagen, met de naam `dfnls-show-{id}-part-{NNNNN}.webm` en met `post_parent` naar de uitzending.
4. De tabel `wp_dfnls_replay_parts` bewaart de volgorde en de duur van elke chunk.

### Hoe de replay werkt

Bij het laden van de pagina in replaymodus:

1. roept de kijker `GET /wp-json/df-nls/v1/shows/{id}/replay` aan, die de geordende lijst met segmenten en de tijdlijn van de gebeurtenissen teruggeeft;
2. worden de segmenten na elkaar geladen via de `ended`-gebeurtenis van het ``-element (de ingebouwde terugval);
3. maakt een MediaSource-variant een naadloze aaneenschakeling mogelijk als de browser dat ondersteunt;
4. wordt de afspeelpositie (de opgetelde tijd) vergeleken met de `offset_ms` van elke gebeurtenis; zodra dat punt wordt bereikt, voert de kijker lokaal hetzelfde gedrag uit als tijdens de uitzending (overlay tonen, flitscoupon, bericht).

### Opslag en schijfruimte

Een orde van grootte: een uitzending van een uur op 1,5 Mbps video plus 96 kbps audio levert ongeveer **720 MB** aan WebM-bestanden op. Met 90 dagen bewaartermijn en 4 uitzendingen per maand rekent u op ongeveer 10 GB schijfruimte voor de replays.

**MIME en upload**: de plugin voegt een filter `upload_mimes` toe om `video/webm` en `video/mp4` in de mediabibliotheek toe te laten. Controleer of uw server geen te strikte regel `LimitRequestBody` of `upload_max_filesize` hanteert (mik op minstens 20 MB per chunk).

## Integratie: shortcode, blok, directe URL

### Directe publieke URL

Elke gepubliceerde uitzending krijgt automatisch een eigen URL:

```
https://uw-site.com/live/uw-slug/
```

Dat is de eenvoudigste manier: deel die link met uw publiek.

### Shortcode

Om een uitzending in een bestaande pagina of een bestaand bericht op te nemen:

```
[dfnls_live id="42"]
[dfnls_live id="42" mode="live"]
[dfnls_live id="42" mode="replay"]
[dfnls_live id="42" mode="auto"]
```

Beschikbare modi:

- `auto` (standaard): herkent de status van de uitzending en toont live, wachtscherm of replay;
- `live`: forceert de uitzendweergave (handig om te testen);
- `replay`: forceert de replaymodus, ook als de uitzending nog loopt.

### Gutenberg-blok

Zoek in de blokeditor naar _"Live Shopping"_. Het blok ondersteunt de uitlijningen `wide` en `full`, en biedt in het inspectiepaneel een keuzelijst voor de uitzending en een keuzelijst voor de modus.

### Eigen PHP-template

Het CPT gebruikt `templates/single-live-show.php`. Om dat te overschrijven, kopieert u het bestand naar uw thema onder `uw-thema/df-native-live-shopping/single-live-show.php`.

## Meertaligheid met Polylang

De plugin meldt het CPT `dfnls_live_show` bij Polylang aan als vertaalbaar. Is Polylang al geïnstalleerd bij de activering:

- dan kan elke uitzending een versie in FR, EN, ES, DE, IT en andere talen hebben;
- worden de belangrijkste metagegevens (`_dfnls_product_ids`, `_dfnls_scheduled_at`, de opties van de uitzending) automatisch tussen de vertalingen gekopieerd;
- worden de 5 ingebouwde talen (FR, EN, ES, DE, IT) automatisch geladen volgens de WordPress-locale.

**Tip voor Polylang Pro**: gebruikt u Polylang Pro en zijn uw WooCommerce-producten zelf vertaald, dan moet elke vertaling van de uitzending aan de bijbehorende taalversie van de producten worden gekoppeld. De plugin koppelt de product-ID's niet automatisch over talen heen.

## HPOS en compatibiliteit

De plugin verklaart officieel haar compatibiliteit met de high performance order storage van WooCommerce (HPOS), via `FeaturesUtil`. U kunt HPOS dus zonder risico voor de winkelwagenbrug inschakelen.

Ook compatibel met:

- WordPress Multisite (installatie per site, geen netwerkmodus);
- gedeelde hosting (o2switch, OVH, Infomaniak, PlanetHoster), want de signalering werkt met REST-polling en niet met WebSockets;
- cacheplugins (WP Rocket, WP Super Cache), want de REST-endpoints van de plugin worden automatisch uitgesloten.

## Beveiliging en capabilities

De plugin voegt twee eigen capabilities toe:

- `manage_dfnls_lives`: uitzendingen aanmaken, bewerken en verwijderen, plus toegang tot de instellingen;
- `host_dfnls_lives`: toegang tot de presentatorconsole en het starten en stoppen van een uitzending.

Beide capabilities gaan standaard naar de rollen `administrator` en `shop_manager`. Om een gebruiker alleen het recht te geven om te presenteren zonder uitzendingen te kunnen aanmaken:

```
$user = get_user_by('login', 'presentator');
$user->add_cap('host_dfnls_lives');
```

### REST-nonces

Alle actieroutes (POST) zijn beveiligd met de nonce `wp_rest`. De kijker en de presentator krijgen hun eigen nonce bij het laden van de pagina, via `wp_localize_script`.

### MIME-validatie bij uploads

Het uploaden van replaychunks wordt strikt gevalideerd met `wp_check_filetype_and_ext`, zodat alleen `video/webm` en `video/mp4` worden aanvaard. De bestanden worden aan de serverzijde hernoemd (`dfnls-show-{id}-part-{NNNNN}.webm`).

## Cron en onderhoud

Bij de activering worden twee WordPress-crons ingepland:

- `dfnls_cleanup_expired_replays`: **dagelijks**. Verwijdert de replays van uitzendingen die meer dan N dagen geleden zijn afgelopen (instelbare bewaartermijn). Gebruikt `wp_delete_attachment(..., true)` om ook het fysieke bestand te wissen.
- `dfnls_cleanup_stale_signaling`: **elk uur**. Ruimt signaleringsberichten ouder dan 24 uur op, plus sessies die meer dan 90 seconden inactief zijn.

**WP-Cron uitgeschakeld**: hebt u WP-Cron uitgeschakeld ten gunste van een systeemcron, zorg er dan voor dat `wp-cron.php` minstens één keer per uur wordt aangeroepen, zodat de opruimingen doorgaan.

## Voor ontwikkelaars: REST API

Alle routes staan onder de namespace `df-nls/v1`.

### Show

- `GET /shows/{id}`: haalt een uitzending op (status, producten, opties)
- `POST /shows/{id}/join`: sluit aan als kijker of presentator (body: `peer_id`, `role`)
- `POST /shows/{id}/leave`: verlaat netjes
- `POST /shows/{id}/heartbeat`: houdt de sessie open (automatisch elke 15 seconden aan kijkerszijde)
- `POST /shows/{id}/start`: start de uitzending (alleen de presentator)
- `POST /shows/{id}/end`: beëindigt de uitzending (alleen de presentator)
- `GET /shows/{id}/viewers`: teller van de actieve kijkers

### WebRTC-signalering

- `POST /signal/send`: stuurt een SDP- of ICE-bericht naar een externe peer
- `GET /signal/pull?peer={id}`: haalt de wachtende berichten op en voert impliciet een heartbeat uit

### Events

- `POST /shows/{id}/event`: legt een gebeurtenis vast (spotlight, bericht, coupon)
- `GET /shows/{id}/events?since={id}`: haalt de gebeurtenissen op vanaf een bepaald ID

### Chat

- `GET /shows/{id}/chat?since={id}`: haalt de berichten op vanaf een bepaald ID
- `POST /shows/{id}/chat`: verstuurt een bericht

### Winkelwagenbrug

- `POST /cart/add`: voegt een product toe aan de winkelwagen met bronregistratie (`show_id`, `product_id`, `quantity`)
- `GET /cart/summary`: teller en totaal van de huidige winkelwagen

### Opname en replay

- `POST /shows/{id}/replay/chunk`: multipart-upload van een WebM-chunk
- `GET /shows/{id}/replay`: segmenten plus de tijdlijn met gebeurtenissen voor het afspelen

## Structuur van de plugin (PSR-4)

```
df-native-live-shopping/
├── df-native-live-shopping.php        # Bootstrap
├── uninstall.php
├── readme.txt
├── assets/
│   ├── js/    (host.js, viewer.js, admin.js, block-editor.js)
│   └── css/   (host.css, viewer.css, admin.css)
├── languages/                          # 5 .po/.mo plus .pot
├── templates/                          # single-live-show.php, viewer-container.php, ...
└── src/
    ├── Plugin.php
    ├── Activator.php   Deactivator.php
    ├── PostType/       (LiveShow.php)
    ├── Database/       (Schema plus 5 Repository.php)
    ├── Admin/          (AdminPages, MetaBoxes, SettingsPage)
    ├── Api/            (RestController, SignalingController, CartController)
    ├── Recording/      (RecordingHandler)
    ├── Replay/         (ReplayHandler)
    ├── Frontend/       (Renderer, Shortcode, Block)
    └── Compat/         (PolylangCompat)
```

Hoofdnamespace: `DataFireflyNativeLiveShopping`, met een handmatige PSR-4-autoloader die in `df-native-live-shopping.php` wordt aangegeven.

## Probleemoplossing

### De kijkers zien de video niet

- Controleer of de site op HTTPS draait (verplicht voor WebRTC).
- Open de browserconsole aan kijkerszijde en zoek naar fouten als `ICE failed` of `connection state failed`.
- Stel een TURN-server in als uw publiek veel mobiele 4G-gebruikers telt.
- Controleer of de uploadbandbreedte van de presentator volstaat (test met fast.com aan presentatorzijde).

### De presentatorconsole vindt de camera niet

- Controleer of de browser wel toestemming heeft gekregen (het slotje in de adresbalk).
- Controleer op macOS de systeemrechten: _Systeeminstellingen → Beveiliging → Camera_.
- Sluit andere programma's die de camera gebruiken (Zoom, Teams, OBS en dergelijke).

### De replaychunks worden niet geüpload

- Controleer `upload_max_filesize` en `post_max_size` in php.ini (mik op minstens 20 MB).
- Controleer zo nodig `LimitRequestBody` aan Apache-zijde.
- Bekijk het activiteitenlogboek van de presentatorconsole om de exacte fout te vinden.
- Controleer de rechten van de map `wp-content/uploads`.

### De winkelwagen onthoudt de toevoegingen niet

- Controleer of geen enkele cacheplugin de endpoints `/wp-json/df-nls/v1/*` cachet.
- Controleer of de WooCommerce-cookies (`woocommerce_cart_hash`, `wp_woocommerce_session_*`) wel worden geplaatst.
- Controleer bij strikte HTTPS of de cookies de vlag `Secure` dragen.

### De replays nemen te veel ruimte in

- Verkort de bewaartermijn in de instellingen (bijvoorbeeld van 90 naar 30 dagen).
- Schakel de opname uit voor uitzendingen waar die niet nodig is (het vakje "Replay toestaan" in de metabox _Opties_).
- Verlaag de bitrate door `host.js` aan te passen (variabele `videoBitsPerSecond`).

## Verwijderen

Bij een gewone deactivering blijven de gegevens behouden en worden de crons uit de planning gehaald. Bij het **volledig verwijderen** van de plugin via _Plugins_ voert `uninstall.php` het volgende uit:

- de 5 eigen tabellen worden verwijderd;
- alle opties `dfnls_*` worden verwijderd;
- de capabilities worden bij de rollen weggehaald;
- de crons worden uit de planning gehaald;
- optioneel worden de CPT's en alle replaybijlagen verwijderd, als de optie `dfnls_uninstall_delete_data` vóór het verwijderen was ingeschakeld.

**Let op**: standaard worden de uitzendingen en hun replays bij het verwijderen NIET gewist. Wilt u alles verwijderen, schakel dan vóór het verwijderen de optie _Alle gegevens verwijderen bij het verwijderen van de plugin_ in bij de instellingen.

## Support en toekomst

Technische ondersteuning is 12 maanden inbegrepen via de DataFirefly-klantomgeving. De updates van de plugin haalt u op via uw account, met een e-mailmelding bij grote versies.

Ideeën op de roadmap:

- automatisch overschakelen naar een SFU boven een bepaald aantal kijkers;
- livepeilingen (poll.open en poll.close zijn al gereserveerd in het gebeurtenissenprotocol);
- ingebouwde analyses (gemiddelde kijktijd, conversiepercentage per uitzending);
- meerdere presentatoren (twee tegelijk).
