Funktion „Auf dem Fernseher weiter ansehen“ in Android TV einbinden

In diesem Leitfaden wird beschrieben, wie Sie die Funktion „Auf dem Fernseher weiter ansehen“ mithilfe des Engage SDK in Ihre Android TV-App einbinden.

Vorarbeit

Führen Sie die Schritte unter „Vorarbeit“ im Startleitfaden aus.

Integration

Entitäten erstellen

Im SDK sind verschiedene Entitäten definiert, um die einzelnen Elementtypen darzustellen. Der Cluster „Auf dem Fernseher weiter ansehen“ unterstützt die folgenden Entitäten:

  1. MovieEntity
  2. TvEpisodeEntity
  3. LiveStreamingVideoEntity
  4. VideoClipEntity

Geben Sie die plattformspezifischen URIs und Posterbilder für diese Entitäten an.

Erstellen Sie außerdem Wiedergabe-URIs für jede Plattform, z. B. Android TV, Android oder iOS, falls noch nicht geschehen. Wenn ein Nutzer die Wiedergabe auf einer Plattform fortsetzt, verwendet die App einen gezielten Wiedergabe-URI, um die Videoinhalte abzuspielen.

// Required. Set this when you want continue watching entities to show up on
// Google TV
val playbackUriTv = PlatformSpecificUri.Builder()
    .setPlatformType(PlatformType.TYPE_ANDROID_TV)
    .setActionUri(Uri.parse("https://www.example.com/entity_uri_for_tv"))
    .build()

// Required. Set this when you want continue watching entities to show up on
// Google TV Android app, Entertainment Space, Playstore Widget
val playbackUriAndroid = PlatformSpecificUri.Builder()
    .setPlatformType(PlatformType.TYPE_ANDROID_MOBILE)
    .setActionUri(Uri.parse("https://www.example.com/entity_uri_for_android"))
    .build()

// Optional. Set this when you want continue watching entities to show up on
// Google TV iOS app
val playbackUriIos = PlatformSpecificUri.Builder()
    .setPlatformType(PlatformType.TYPE_IOS)
    .setActionUri(Uri.parse("https://www.example.com/entity_uri_for_ios"))
    .build()

val platformSpecificPlaybackUris =
    Arrays.asList(playbackUriTv, playbackUriAndroid, playbackUriIos)

Für Posterbilder sind ein URI und Pixelabmessungen (Höhe und Breite) erforderlich. Sie können mehrere Posterbilder angeben, um verschiedene Formfaktoren anzusprechen. Achten Sie jedoch darauf, dass alle Bilder ein Seitenverhältnis von 16:9 und eine Mindesthöhe von 200 Pixeln haben, damit die Entität „Auf dem Fernseher weiter ansehen“ korrekt angezeigt wird, insbesondere im Entertainment Space von Google. Bilder mit einer Höhe von weniger als 200 Pixeln werden möglicherweise nicht angezeigt.

val images = Arrays.asList(
    Image.Builder()
        .setImageUri(Uri.parse("http://www.example.com/entity_image1.png"))
        .setImageHeightInPixel(300)
        .setImageWidthInPixel(169)
        .build(),
    Image.Builder()
        .setImageUri(Uri.parse("http://www.example.com/entity_image2.png"))
        .setImageHeightInPixel(640)
        .setImageWidthInPixel(360)
        .build()
    // Consider adding other images for different form factors
)

MovieEntity

In diesem Beispiel wird gezeigt, wie Sie eine MovieEntity mit allen erforderlichen Feldern erstellen:

val movieEntity = MovieEntity.Builder()
   .setWatchNextType(WatchNextType.TYPE_CONTINUE)
   .setName("Movie name")
   .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
   .addPosterImages(images)
   // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
   .setLastEngagementTimeMillis(1701388800000)
   // Suppose the duration is 2 hours, it is 72000000 in milliseconds
   .setDurationMills(72000000)
   // Suppose last playback offset is 1 hour, 36000000 in milliseconds
   .setLastPlayBackPositionTimeMillis(36000000)
   .setCallToActionText("Resume")
   .addTag("Action")
   .build()

Wenn Sie Details wie Genres und Altersfreigaben angeben, kann Google TV Ihre Inhalte dynamischer präsentieren und sie den richtigen Zuschauern zeigen.

val genres = Arrays.asList("Action", "Science fiction")
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("PG-13").build()
val contentRatings = Arrays.asList(rating1)
val movieEntity = MovieEntity.Builder()
    ...
    .addGenres(genres)
    .addContentRatings(contentRatings)
    .build()

Entitäten bleiben automatisch 60 Tage lang verfügbar, es sei denn, Sie geben eine kürzere Ablaufzeit an. Legen Sie nur dann eine benutzerdefinierte Ablaufzeit fest, wenn die Entität vor Ablauf dieses Standardzeitraums entfernt werden soll.

// Set the expiration time to be now plus 30 days in milliseconds
val expirationTime = DisplayTimeWindow.Builder()
    .setEndTimestampMillis(now().toMillis()+2592000000).build()
val movieEntity = MovieEntity.Builder()
    ...
    .addAvailabilityTimeWindow(expirationTime)
    .build()

TvEpisodeEntity

In diesem Beispiel wird gezeigt, wie Sie eine TvEpisodeEntity mit allen erforderlichen Feldern erstellen:

val tvEpisodeEntity = TvEpisodeEntity.Builder()
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Episode name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(72000000) // 2 hours in milliseconds
    // 45 minutes and 15 seconds in milliseconds is 2715000
    .setLastPlayBackPositionTimeMillis(2715000)
    .setEpisodeNumber("2")
    .setSeasonNumber("1")
    .setShowTitle("Title of the show")
    .setCallToActionText("Resume")
    .addTag("Comedy")
    .build()

Die String für die Folgennummer (z. B. "2") und die String für die Staffelnnummer (z. B. "1") werden in die richtige Form erweitert, bevor sie auf der Karte „Auf dem Fernseher weiter ansehen“ angezeigt werden. Beachten Sie, dass es sich um numerische Strings handeln sollte. Verwenden Sie nicht „e2“, „Folge 2“, „s1“ oder „Staffel 1“.

Wenn eine bestimmte Fernsehserie nur eine Staffel hat, legen Sie die Staffelnnummer auf 1 fest.

Um die Wahrscheinlichkeit zu maximieren, dass Zuschauer Ihre Inhalte auf Google TV finden, können Sie zusätzliche Daten wie Genres, Altersfreigaben und Verfügbarkeitszeiträume angeben. Diese Details können die Anzeige und die Filteroptionen verbessern.

val genres = Arrays.asList("Action", "Science fiction")
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("PG-13").build()
val contentRatings = Arrays.asList(rating1)
val tvEpisodeEntity = TvEpisodeEntity.Builder()
    ...
    .addGenres(genres)
    .addContentRatings(contentRatings)
    .setSeasonTitle("Season Title")
    .setShowTitle("Show Title")
    .build()

VideoClipEntity

Hier ist ein Beispiel für die Erstellung einer VideoClipEntity mit allen erforderlichen Feldern.

VideoClipEntity stellt einen von Nutzern erstellten Clip dar, z. B. ein YouTube-Video.

val videoClipEntity = VideoClipEntity.Builder()
    .setPlaybackUri(Uri.parse("https://www.example.com/uri_for_current_platform"))
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Video clip name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(600000) //10 minutes in milliseconds
    .setLastPlayBackPositionTimeMillis(300000) //5 minutes in milliseconds
    .addContentRating(contentRating)
    .setCallToActionText("Resume")
    .addTag("Vlog")
    .build()

Optional können Sie den Ersteller, das Erstellerbild, die Erstellungszeit in Millisekunden oder den Verfügbarkeitszeitraum festlegen .

LiveStreamingVideoEntity

Hier ist ein Beispiel für die Erstellung einer LiveStreamingVideoEntity mit allen erforderlichen Feldern.

val liveStreamingVideoEntity = LiveStreamingVideoEntity.Builder()
    .setPlaybackUri(Uri.parse("https://www.example.com/uri_for_current_platform"))
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Live streaming name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(72000000) //2 hours in milliseconds
    .setLastPlayBackPositionTimeMillis(36000000) //1 hour in milliseconds
    .addContentRating(contentRating)
    .setCallToActionText("Resume")
    .addTag("Live")
    .build()

Optional können Sie die Startzeit, den Sender, das Sendersymbol oder den Verfügbarkeitszeitraum für die Live-Streaming-Entität festlegen.

Ausführliche Informationen zu Attributen und Anforderungen finden Sie in der API Referenz.

Daten für den Cluster „Auf dem Fernseher weiter ansehen“ angeben

AppEngagePublishClient ist für die Veröffentlichung des Clusters „Auf dem Fernseher weiter ansehen“ verantwortlich. Mit der Methode publishContinuationCluste können Sie ein ContinuationCluster-Objekt veröffentlichen.

Initialisieren Sie den Client und prüfen Sie die Verfügbarkeit des Dienstes wie im Startleitfaden beschrieben.

client.publishContinuationCluster(
    PublishContinuationClusterRequest
        .Builder()
        .setContinuationCluster(
            ContinuationCluster.Builder()
                .setAccountProfile(accountProfile)
                .addEntity(movieEntity1)
                .addEntity(movieEntity2)
                .addEntity(tvEpisodeEntity1)
                .addEntity(tvEpisodeEntity2)
                .setSyncAcrossDevices(true)
                .build()
        )
        .build()
)

Wenn der Dienst die Anfrage erhält, werden die folgenden Aktionen in einer Transaktion ausgeführt:

  • Vorhandene ContinuationCluster-Daten des Entwicklungspartners werden entfernt.
  • Daten aus der Anfrage werden geparst und im aktualisierten ContinuationCluster gespeichert.

Im Falle eines Fehlers wird die gesamte Anfrage abgelehnt und der vorhandene Zustand beibehalten.

Die Veröffentlichungs-APIs sind Upsert-APIs. Sie ersetzen den vorhandenen Inhalt. Wenn Sie eine bestimmte Entität im Cluster „Auf dem Fernseher weiter ansehen“ aktualisieren möchten, müssen Sie alle Entitäten noch einmal veröffentlichen.

Daten für den Cluster „Auf dem Fernseher weiter ansehen“ sollten nur für Konten von Erwachsenen bereitgestellt werden. Veröffentlichen Sie nur, wenn das Kontoprofil zu einem Erwachsenen gehört.

Geräteübergreifende Synchronisierung

Mit setSyncAcrossDevices wird gesteuert, ob die ContinuationCluster-Daten eines Nutzers auf verschiedenen Geräten wie Fernsehern, Smartphones und Tablets synchronisiert werden. Die geräteübergreifende Synchronisierung ist standardmäßig deaktiviert.

Werte:

  • true: Die Daten des Clusters „Auf dem Fernseher weiter ansehen“ werden auf allen Geräten des Nutzers freigegeben, um eine nahtlose Wiedergabe zu ermöglichen. Wir empfehlen diese Option für die beste geräteübergreifende Nutzung.
  • false: Die Daten des Clusters „Auf dem Fernseher weiter ansehen“ sind auf das aktuelle Gerät beschränkt.

Außerdem müssen Sie ein AccountProfile mit einer Konto-ID angeben, damit die Inhalte zwischen Geräten synchronisiert werden können. Weitere Informationen finden Sie unter Kontoprofil erstellen.

Die Media-App muss eine klare Einstellung zum Aktivieren oder Deaktivieren der geräteübergreifenden Synchronisierung bieten. Erklären Sie dem Nutzer die Vorteile und speichern Sie die Präferenz des Nutzers einmal. Wenden Sie sie dann entsprechend in publishContinuationCluster an.

// Example to allow cross device syncing.
client.publishContinuationCluster(
    PublishContinuationClusterRequest
        .Builder()
        .setContinuationCluster(
            ContinuationCluster.Builder()
                .setAccountProfile(accountProfile)
                .setSyncAcrossDevices(true)
                .build()
        )
        .build()
)

Damit Sie unsere geräteübergreifende Funktion optimal nutzen können, müssen Sie prüfen, ob die App die Nutzereinwilligung einholt, und SyncAcrossDevices auf true setzen. So können Inhalte nahtlos auf verschiedenen Geräten synchronisiert werden, was zu einer besseren Nutzererfahrung und einer höheren Interaktion führt. Ein Partner, der diese Funktion implementiert hat, verzeichnete beispielsweise eine Steigerung der Klicks auf „Auf dem Fernseher weiter ansehen“ um 40 %, da seine Inhalte auf mehreren Geräten angezeigt wurden.

Engage-Daten löschen

Wenn Sie die Daten eines Nutzers vor Ablauf der standardmäßigen Aufbewahrungsdauer von 60 Tagen manuell vom Google TV-Server löschen möchten, verwenden Sie die Methode deleteClusters. Nach Erhalt der Anfrage löscht der Dienst alle vorhandenen Engage-Daten für das Kontoprofil oder für das gesamte Konto.

Die DeleteReason Enum definiert den Grund für das Löschen von Daten. Mit dem folgenden Code werden die Daten für „Auf dem Fernseher weiter ansehen“ beim Abmelden entfernt.


// If the user logs out from your media app, you must make the following call
// to remove continue watching data from the current google TV device,
// otherwise, the continue watching data will persist on the current
// google TV device until 60 days later.
client.deleteClusters(
    DeleteClustersRequest.Builder()
        .setAccountProfile(AccountProfile())
        .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
        .setSyncAcrossDevices(true)
        .build()
)

Test

Verwenden Sie die Überprüfungs-App, um zu prüfen, ob die Engage SDK-Integration korrekt funktioniert.

Nachdem Sie die Veröffentlichungs-API aufgerufen haben, prüfen Sie in der Überprüfungs-App, ob Ihre Daten korrekt veröffentlicht werden. Ihr Cluster „Auf dem Fernseher weiter ansehen“ sollte als separate Zeile in der Benutzeroberfläche der App angezeigt werden.

  • Testen Sie diese Aktionen in Ihrer App:
    • Melden Sie sich an.
    • Wechseln Sie zwischen Profilen(falls zutreffend).
    • Starten Sie ein Video, pausieren Sie es oder kehren Sie zur Startseite zurück.
    • Schließen Sie die App während der Videowiedergabe.
    • Entfernen Sie ein Element aus der Zeile „Auf dem Fernseher weiter ansehen“ (falls unterstützt).
  • Prüfen Sie nach jeder Aktion, ob Ihre App die API publishContinuationClusters aufgerufen hat und ob die Daten in der Überprüfungs-App korrekt angezeigt werden.
  • In der Überprüfungs-App wird für korrekt implementierte Entitäten ein grünes Häkchen „Alles in Ordnung“ angezeigt.

    Screenshot: Bestätigungs-App erfolgreich
    Abbildung 1. Überprüfungs-App – Erfolgreich
  • In der Überprüfungs-App werden alle problematischen Entitäten gekennzeichnet.

    Screenshot des Fehlers in der Bestätigungs-App
    Abbildung 2. Überprüfungs-App – Fehler
  • Wenn Sie Fehler bei Entitäten beheben möchten, wählen Sie die Entität in der Überprüfungs-App mit der Fernbedienung aus und klicken Sie darauf. Die spezifischen Probleme werden angezeigt und rot hervorgehoben (siehe Beispiel unten).

    Fehlerdetails zur Bestätigungs-App
    Abbildung 3. Überprüfungs-App – Fehlerdetails