book_path: /distribute/other-docs/_book.yaml project_path: /distribute/other-docs/_project.yaml
In diesem Leitfaden wird beschrieben, wie du die Funktion „Auf dem Fernseher weiter ansehen“ mithilfe des Engage SDK in deine Android TV-App einbindest.
Vorbereitung
Führen Sie die Schritte im Startleitfaden unter Vorbereitung aus.
Integration
Entitäten erstellen
Im SDK sind verschiedene Entitäten definiert, um die einzelnen Elementtypen darzustellen. Der Fortsetzungscluster unterstützt die folgenden Einheiten:
Geben Sie die plattformspezifischen URIs und Posterbilder für diese Elemente an.
Erstelle außerdem Wiedergabe-URIs für jede Plattform, z. B. Android TV, Android oder iOS, falls noch nicht geschehen. Wenn ein Nutzer also auf jeder Plattform weiterschaut, 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 eine URI und Pixelabmessungen (Höhe und Breite) erforderlich. Wenn du mehrere Posterbilder bereitstellst, kannst du verschiedene Formfaktoren ansprechen. Achte aber darauf, dass alle Bilder ein Seitenverhältnis von 16:9 und eine Mindesthöhe von 200 Pixel haben, damit die Entität „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 ein MovieEntity-Objekt 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)
.build()
Wenn du Details wie Genres und Altersfreigaben angibst, kann Google TV deine Inhalte auf dynamischere Weise präsentieren und sie mit den richtigen Zuschauern in Verbindung bringen.
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, sofern Sie keine kürzere Ablaufzeit angeben. Legen Sie nur dann ein benutzerdefiniertes Ablaufdatum fest, wenn das Element vor diesem Standardzeitraum 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 ein 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")
.build()
Die Folgennummer (z. B. "2") und die Staffelnnummer (z. B. "1") werden in die richtige Form gebracht, bevor sie auf der Karte „Weiter ansehen“ angezeigt werden. Es muss sich um einen numerischen String handeln. Geben Sie nicht „e2“, „Folge 2“, „s1“ oder „Staffel 1“ ein.
Wenn eine bestimmte TV-Serie nur eine Staffel hat, legen Sie die Staffelnnummer auf 1 fest.
Damit Zuschauer deine Inhalte auf Google TV leichter finden, solltest du 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 das Erstellen eines VideoClipEntity mit allen erforderlichen Feldern.
VideoClipEntity steht für einen vom Nutzer erstellten Clip wie 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)
.build()
Optional können Sie den Ersteller, das Erstellerbild, die Erstellungszeit in Millisekunden oder das Verfügbarkeitszeitfenster festlegen .
LiveStreamingVideoEntity
Hier ist ein Beispiel für das Erstellen eines 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)
.build()
Optional können Sie die Startzeit, den Sender, das Senderlogo oder das Verfügbarkeitszeitfenster für die Livestreaming-Einheit festlegen.
Ausführliche Informationen zu Attributen und Anforderungen finden Sie in der API-Referenz.
Daten für den Fortsetzungscluster angeben
AppEngagePublishClient ist für die Veröffentlichung des Continuation-Clusters verantwortlich.
Mit der Methode publishContinuationCluste veröffentlichen Sie ein ContinuationCluster-Objekt.
Achten Sie darauf, den Client zu initialisieren und die Dienstverfügbarkeit zu prüfen, 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 empfängt, werden die folgenden Aktionen in einer Transaktion ausgeführt:
- Vorhandene
ContinuationCluster-Daten des Entwicklerpartners werden entfernt. - Die Daten aus der Anfrage werden geparst und im aktualisierten
ContinuationClustergespeichert.
Bei einem Fehler wird die gesamte Anfrage abgelehnt und der vorhandene Status beibehalten.
Die Publish-APIs sind Upsert-APIs. Sie ersetzen die vorhandenen Inhalte. Wenn Sie eine bestimmte Entität im Fortsetzungscluster aktualisieren müssen, müssen Sie alle Entitäten noch einmal veröffentlichen.
Daten für Fortsetzungscluster sollten nur für Konten von Erwachsenen bereitgestellt werden. Veröffentlichen Sie nur, wenn das Kontoprofil einem Erwachsenen gehört.
Geräteübergreifende Synchronisierung
Mit dem Flag SyncAcrossDevices wird gesteuert, ob die ContinuationCluster-Daten eines Nutzers auf Geräten wie Fernsehern, Smartphones und Tablets synchronisiert werden. Die geräteübergreifende Synchronisierung ist standardmäßig deaktiviert.
Werte:
true: Daten von Fortsetzungsclustern werden auf allen Geräten des Nutzers geteilt, um eine nahtlose Wiedergabe zu ermöglichen. Wir empfehlen diese Option dringend, damit Sie die beste geräteübergreifende Nutzung erzielen.false: Daten für die Fortsetzung sind auf das aktuelle Gerät beschränkt.
Einwilligung einholen
Die Media-Anwendung muss eine eindeutige Einstellung zum Aktivieren oder Deaktivieren der geräteübergreifenden Synchronisierung bieten. Erläutern Sie dem Nutzer die Vorteile und speichern Sie die Nutzereinstellung einmalig und wenden Sie sie 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 die geräteübergreifende Funktion optimal nutzen können, müssen Sie dafür sorgen, dass die App die Einwilligung der Nutzer einholt und SyncAcrossDevices auf true festgelegt ist. 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 einen Anstieg der Klicks auf „Weiter ansehen“ um 40 %, da seine Inhalte auf mehreren Geräten angezeigt wurden.
Daten zur Videoermittlung löschen
Wenn Sie die Daten eines Nutzers vor dem standardmäßigen Aufbewahrungszeitraum von 60 Tagen manuell vom Google TV-Server löschen möchten, verwenden Sie die Methode deleteClusters. Nach Eingang der Anfrage löscht der Dienst alle vorhandenen Daten zur Videoermittlung für das Kontoprofil oder für das gesamte Konto.
Das Enum DeleteReason definiert den Grund für das Löschen von Daten.
Mit dem folgenden Code werden die Daten zum Fortsetzen der Wiedergabe 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()
)
Testen
Verwenden Sie die Bestätigungs-App, um zu prüfen, ob die Engage SDK-Integration richtig funktioniert.
Nachdem Sie die Publish API aufgerufen haben, prüfen Sie in der Bestätigungs-App, ob Ihre Daten korrekt veröffentlicht werden. Ihr Fortsetzungscluster sollte in der Benutzeroberfläche der App als separate Zeile angezeigt werden.
- Testen Sie diese Aktionen in Ihrer App:
- Melden Sie sich an.
- Wechseln Sie zwischen Profilen(falls zutreffend).
- Ein Video starten und pausieren oder zur Startseite zurückkehren
- Schließe die App während der Videowiedergabe.
- Entferne ein Element aus der Zeile „Weiter ansehen“ (falls unterstützt).
- Prüfen Sie nach jeder Aktion, ob Ihre App die
publishContinuationClustersAPI aufgerufen hat und die Daten in der Bestätigungs-App korrekt angezeigt werden. In der Überprüfungs-App wird für korrekt implementierte Rechtssubjekte ein grünes Häkchen mit dem Hinweis „Alles in Ordnung“ angezeigt.
Abbildung 1: Erfolgreiche Überprüfung der App Die Verifizierungs-App kennzeichnet alle problematischen Einheiten.
Abbildung 2. Fehler bei der Bestätigungs-App Wenn Sie Probleme mit Entitäten beheben möchten, wählen Sie die Entität in der Bestätigungs-App mit der TV-Fernbedienung aus und klicken Sie darauf. Die spezifischen Probleme werden angezeigt und zur Überprüfung rot hervorgehoben (siehe Beispiel unten).
Abbildung 3: Fehlerdetails zur Bestätigungs-App