Videos sicher einbinden

(Nachtrag 2022: Video.api wurde grundlegend verändert und ist dadurch zwar einfacher, aber nicht mehr günstig oder gar kostenlos. Ich empfehle daher die Stream-Funktion von bunny.net oder vadoo.tv)

Vor Downloadversuchen sichere Videos in Websites einzubinden ist nicht trivial. Ungeschützt können Sie direkt per Rechtsklick oder nach einem kurzem Blick in den Quelltext per URL geladen werden. Verwendet man Dienste wie Vimeo oder Youtube, braucht es auch nur einen entsprechenden Downloader wie „Video Download Helper“, „JDownloader“ oder ClipGrab. Selbst HLS-Streams (webstream.eu, Wistia etc.) lassen sich z.B. mit Video Download Helper o.Ä. per Zusatzmodul laden. Um einen Download zu verhindern, braucht es also einen erweiterten Schutz. VdoCipher ist ein populärer Dienst, der das bereits ab 99$ pro Jahr anbietet. Hat man aber nur wenige Videos, die man auf seiner Webseite sicher einbinden möchte, gibt es dazu eine kostenlose Alternative: api.video – kostenlos, aber nicht ganz einfach zu handhaben. Ich möchte deswegen hier eine Anleitung veröffentlichen, die das Einbinden in der Praxis Schritt für Schritt erklärt:

  • Video codieren via Handbrake
  • Upload zu api.video
  • Einbindung des iframes in die Webseite
  • Erstellung eines responsive iframes (Danke an Sven Wolfermann)
    • dadurch passt sich Breite und Höhe (!) des Video-iframes ans Mobiltelefon etc. an.

Kostenloser Plan von api.video

Im Gegensatz zum teuren Premium-Plan gibt es ein paar Unterschiede: Es stehen pro Monat kostenlos (nur) eine Stunde Videoupload zur Verfügung; es kann aber weitere Videozeit hinzugekauft werden: einmalige Upload-Kosten: +1 Stunde = 10 $. Weiteres Hosting, Encoding und Streaming sind kostenlos. Der Stream wird auf 720p begrenzt, was jedoch in der Regel reichen sollte. Das Video wird aber genauso gut geschützt (mit 128 Bit AES verschlüsselt und optional via Token). Ich habe das Resultat der Standard-Ergebnisses getestet und nicht geschafft, es auf irgendeine Art herunterzuladen.

Ich werde den Umgang mit der API via Terminal beschreiben. Es gibt von api.video aber bereits SDKs für PHP und Node.js (Java in Arbeit); api.video arbeitet auch an Plugins für WordPress und Moodle.

Los geht’s:

Handbrake

Da der Upload gesplittet werden muss, wenn er 128MB überschreitet, sollte das Video zuerst mit Handbrake optimiert werden:

  • Handbrake herunterladen und installieren
  • Ausführen und entsprechendes Video auswählen
  • Mit der Voreinstellung Web/Gmail Large 720p encodieren:

Upload des Video zu api.video

Diese Anleitung basiert auf https://docs.api.video

Account anlegen

Token generieren

curl -X POST \
https://ws.api.video/auth/api-key \
-H 'Content-Type: application/json' \
-d '{"apiKey": "EIGENE_API_EINFUEGEN"}'\
> 01_token.txt

GROSSBUCHSTABEN sind Platzhalter für die echten Daten. Es wird die Datei 01_token.txt angelegt. Der Access-Token wird im Folgenden benötigt:

{"token_type":"Bearer","expires_in":3600,"access_token":"ACCESS_TOKEN","refresh_token":"REFRESH_TOKEN"}

Ressource anlegen

curl -X POST \
  https://ws.api.video/videos \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -d '{
    "title":"Titel für das Video",
    "description":"Video-Beschreibung"
  }' \
> 02_upload_info.txt

Es wird die Datei 02_upload_info.txt angelegt, die den Upload-Link und weitere Infos wie VideoID enthält. Diese Informationen werden für den Upload benötigt, und um später Änderungen am Video vorzunehmen (Titel, Thumbnail).

Beispiel für 02_upload_info.txt:

{
    "videoId": "VIDEO_ID",
    "title": "TITEL",
    "description": "BESCHREIBUNG",
    "public": true,
    "publishedAt": "2019-03-01T22:07:08+01:00",
    "tags": [],
    "metadata": [],
    "source": {
        "type": "upload",
        "uri": "/videos/VIDEO_ID/source"
    },
    "assets": {
        "iframe": "<iframe src=\"https://embed.api.video/vod/VIDEO_ID\" width=\"100%\" height=\"100%\" frameborder=\"0\" scrolling=\"no\" allowfullscreen=\"\"></iframe>",
        "player": "https://embed.api.video/vod/VIDEO_ID",
        "hls": "https://cdn.api.video/vod/VIDEO_ID/hls/manifest.m3u8",
        "thumbnail": "//www.gasperl.at/wp-content/swift-ai/images/__e/cdn.api.video/vod/VIDEO_ID/thumbnail-jpg.webp"
    }
}

Video hochladen

curl -X POST \
  https://ws.api.video/videos/VIDEO_ID/source \
  -H 'content-type: multipart/form-data' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -F file=@/Users/USER/VIDEO.mp4

/Users/… bezieht sich auf den Pfad, der am Mac üblich ist. Er wird in Windows oder Linux anders lauten. Ich habe hier den absoluten Pfad verwendet; ein relativer müsste auch funktionieren (~/VIDEO.mp4).

Einbinden in die Webseite

HTML

<div class="embed-container">
<iframe src="https://embed.api.video/vod/VIDEO_ID" width="864" height="486" frameborder="0" allowfullscreen></iframe>
</div>

width und height sind Beispielwerte

CSS

/* iframe videos */
.embed-container {
  position: relative; 
  padding-bottom: 56.25%; /* ratio 16x9 */
  overflow: hidden; 
  width: 100%;
  height: auto;
}
.embed-container iframe {
  position: absolute; 
  top: 0; 
  left: 0; 
  width: 100%; 
  height: 100%; 
}

Bei einem Videoverhältnis von 4:3

/* ratio 4x3 */
.embed-container.ratio4x3 {
  padding-bottom: 75%;
}

Video bearbeiten

Titel ändern

curl -X PATCH \
https://ws.api.video/videos/VIDEO_ID \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-d '{"title":"Neuer Titel","description":"Beschreibung"}'

(„description“:“My video description“ ist optional)

Thumbnail ändern

Um ein Thumbnail zu erstellen:

  • Video mit VLC öffnen und die gewünschte Stelle auswählen.
  • Menü: Video / Schnappschuss (Alt+Cmd+S); Bild wird im User-Bilderordner gespeichert
  • Öffnen mit Vorschau (Mac) oder IrfanView (etc. in Win), im Benutzerordner abspeichern als jpg
  • optional: optimieren mit ImageOptim (Mac) oder ImageOptim online (Win)
curl -X POST \
https://ws.api.video/videos/VIDEO_ID/thumbnail \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-F file=@/Users/USER/FILENAME.jpg

Video löschen

curl -X DELETE \
https://ws.api.video/videos/VIDEO_ID \
-H 'Authorization: Bearer ACCESS_TOKEN'