1. 簡介
接下來請看
「接下來請看」頻道是 Android TV 主畫面上的媒體列,會為使用者提供接下來可觀看的影片。根據系統版本,「接下來請看」媒體列的名稱可能是「播放下一個」或「繼續觀看」。
系統建立並維護這個頻道。此頻道中的每一項都稱為節目。您的應用程式可在「接下來請看」頻道中新增/更新/移除節目,例如使用者途中停止觀看的內容,或是使用者與之互動的內容 (例如系列的下一集或節目的下一季)。
概念
「接下來請看」頻道可讓您的應用程式吸引使用者再次互動。
對於使用者已經互動的「接下來請看」頻道,您可在當中新增/更新/移除內容。可能是未播放完畢的影片,或是推薦的下一個劇集/系列等。
應用程式還可以在觀看後刪除該集節目,並新增該系列新一季的下一集。
「接下來請看」頻道的用途分為四種類型:
- 繼續觀看使用者未看完的影片。
- 推薦觀看下一部影片。舉例來說,如果使用者看完了第 1 集,則可以推薦第 2 集。
- 顯示使用者所觀看系列的新劇集。
- 保留待觀看影劇清單,該清單是由使用者自行新增有趣影片。
本程式碼研究室說明如何在使用者暫停播放影片時,將影片納入「接下來請看」頻道。此外,還包括如何在播放到最後時從「接下來請看」中移除影片,以及如何在下一集上架時新增影片。
本程式碼研究室並未涵蓋「接下來請看」的新發布劇集用途和待觀看影劇清單用途。
「接下來請看」的電影和電視劇集
「接下來請看」頻道是 Android TV 主畫面中一項非常重要的功能,它可以幫助使用者繼續觀看未看完的電影和電視節目。這對於觀看電視劇集的使用者來說尤為重要,因為電視影集通常有很多集,使用者會多次從中斷的地方繼續觀看。
假設使用者回來坐在電視機前,正在決定要看什麼。透過使用「接下來請看」,您的應用程式會允許他們直接在主螢幕,從中斷的地方繼續播放電視劇集。這增加了使用者的再參與度,對應用程式和使用者都有好處。
本程式碼研究室將引導您完成電視參考應用程式,說明如何處理「接下來請看」頻道的不同情況,並解釋有關「接下來請看」功能的 Google 品質指南。本程式碼研究室特別著重於處理電視劇集,但您可以為電影套用類似規則。
適用範圍
此程式碼研究室的程式碼適用於 Android TV 裝置,包括執行 Google TV 服務的裝置。
建構項目
在本程式碼研究室中,您將為電視上的電影/劇集新增、移除及更新「接下來請看」頻道。您的應用程式將會:
- 實作處理電影的不同用途
- 實作處理電視劇集的不同用途
課程內容
- Google 的「接下來請看」品質指南
需求條件
- 對 Android 應用程式開發的基本知識
- Android Studio 4.1 以上的版本,請前往 這裡下載
2. 開始設定
複製範例專案
您可以從 GitHub 存放區下載原始碼:
git clone https://github.com/android/codelab-watchnext-for-movie-tv-episodes.git
您也可以直接從下方連結下載。
開啟 Android Studio,在選單列中依序點選「File」>「Open」,或是在歡迎畫面中點選「Open an Existing Android Studio Project」,然後選取最近複製的資料夾。
瞭解範例專案
專案中共有四個步驟。您將在每個步驟中,根據適用章節中的操作說明新增程式碼。完成一個章節後,您可以比較您的程式碼與 step_x_completed 中的程式碼。
為方便起見,我們為影片清單和 ExoPlayer 新增了一些基本的程式碼,以在應用程式內觀看內容。這會建立一個電視應用程式的基本架構,而這超出了本程式碼研究室的範圍。
我們的目標是,瞭解如何到「接下來請看」頻道新增/刪除/更新未看完和已觀看完畢的影片,讓應用程式再次吸引使用者。
此應用程式的主要元件如下:
FileVideoRepository
是用於載入和查詢影片中繼資料的類別。PlaybackFragment
是影片播放片段。WatchNextPlaybackStateListener
是播放狀態變更監聽器;可監聽播放事件並觸發相關操作。WatchNextWorker
是負責更新「接下來請看」頻道的 worker。WatchNextHelper
這個輔助類別可簡化「接下來請看」頻道的流程。
此程式碼研究室會使用 res/raw/api.json
中的媒體資料,填入「接下來請看」的各個項目。
執行範例專案
執行 step_1。如有問題,請參閱 說明文件 以瞭解如何開始使用。
- 連接 Android TV 或開啟模擬器。
- 依序選擇「step_1」設定和您的 Android 裝置,然後在選單列中按下「run」按鈕。
- 您應該會看到一個簡單的電視應用程式概覽,其中包含四個影片系列,類似於下方的螢幕截圖。
- 瀏覽應用程式的主畫面,熟悉電視參考應用程式。共有四個影片類別:
- Supercharged Clips (Supercharged 系列短片)
- Misc Clips (其他短片)
- Beverly Hillbillies:來自兩個不同電視劇季的幾集電視劇;
- Charlie Chaplin Movies (查理卓別林電影)
- 點選 Beverly Hillbillies 類別中的電視劇集並觀看。本程式碼研究室將說明如何為這些電視劇集新增「接下來請看」節目
您已經瞭解的內容
在本簡介中,您瞭解了以下內容:
- 此程式碼研究室所用的程式碼結構和主要類別。
- 如何設定並執行範例應用程式。
後續步驟
「接下來請看」的品質指南
3. 瞭解「接下來請看」的品質指南
為了提供優質的主畫面體驗,所有在「接下來請看」中新增內容的應用程式都需要保持一致的行為。
具體來說,開發人員需要為電視劇集考量一些情況。為確保「接下來請看」頻道的品質,Google 彙整了一份「接下來請看」頻道的品質指南清單。
如何建構符合 Google 品質標準的「接下來請看」功能
當 Google 評估「接下來請看」功能時,將會驗證以下要點
- 節目暫停/停止播放後,就會新增至「接下來請看」
- 應用程式可以在「接下來請看」專區中繼續播放
- 應用程式及時更新「接下來請看」中的播放位置
- 節目會在播放完畢後從「接下來請看」中移除
- 目前劇集結束時,就會新增下一集
- 應用程式不會將使用者不曾互動的內容新增至「接下來請看」
- 將所有未完成的內容推送至「接下來請看」
- 此應用程式設定了正確且完整的中繼資料,例如季度/集數
- 應用程式無法為同一個電視影集新增多集內容
以下是各項品質規定的說明
- 節目暫停/停止播放後,就會新增至「接下來請看」。
- 如果傳統電影和電視節目尚未播放完畢,應用程式應將這些內容新增到「接下來請看」媒體列
- 應用程式可以在「接下來請看」條目中繼續播放。
- 新增到「接下來請看」頻道的內容會從上次的播放位置恢復播放;載入內容後,影片應會立即開始播放
- 應用程式會即時更新「接下來請看」中的影片播放位置。
- 應用程式需要追蹤播放進度,並在使用者離開影片後,將「接下來請看」頻道更新到最新的播放位置
- 節目會在播放完畢後從「接下來請看」中移除。
- 應用程式應該就像一個好公民一樣,並且具有自我清理的能力。「接下來請看」媒體列是所有應用程式共用的媒體列,我們希望確保該列的內容準確無誤,以維持使用者的信任
- 目前劇集結束時,就會新增下一集。
- 使用者觀看電視影集時,應用程式應將下一集新增到「接下來請看」媒體列,方便使用者繼續觀看該影集
- 應用程式不會將使用者不曾互動的內容新增到「接下來請看」。
- 根據「接下來請看」指南,只有在使用者「開始」觀看時,應用程式才應將電影或電視劇集新增到「接下來請看」頻道
- 我們不建議在「接下來請看」中加入預告片和短片。因為這麼做的使用者再參與度很低
- 將所有未完成的內容推送到「接下來請看」。
- 供應商提供商不應人為限制他們推送到「接下來請看」的資訊卡數量。如果使用者有未看完的內容,供應商應將其推送到「接下來請看」媒體列
- 應用程式會設定正確且完整的中繼資料。
- 請確認與該集節目關聯的中繼資料正確無誤
- 集數、季別號碼和標題必須正確無誤
- 進度條必須與觀看量成正比
- 劇集或系列圖像應出現在圖塊中
- 應用程式應避免新增同一電視影集的多個劇集。
- 針對每部電視影集,應用程式最多只應保留一個「接下來請看」項目。如果兩部不同的劇集都看了一半,則「接下來請看」應只顯示使用者最近觀看的劇集
這些品質規定可協助應用程式提供優質的「接下來請看」使用者體驗。
好的,在謹記這些品質指南的情況下,讓我們直奔主題,開始著手打造「接下來請看」功能。
您已經瞭解的內容
在這個部分中,您已經瞭解到:
- 「接下來請看」的品質規定
後續步驟
將未看完的劇集新增至「接下來請看」頻道
4. 將未看完的內容新增至「接下來請看」
我們將會從基本功能開始說明:將未看完的劇集新增至「接下來請看」。
程式碼研究室將逐步說明如何建立一個 WatchNextProgram
、填寫該集節目的準確中繼資料,例如集數、季別編號和影片類型。「接下來請看」項目可以更新,以便確保能反映使用者的最新播放位置,讓使用者只要按一下節目即可繼續播放。
本節涵蓋以下內容:
- 節目暫停/停止播放後,就會新增至「接下來請看」。
- 應用程式可以在「接下來請看」條目中繼續播放。
- 應用程式會即時更新「接下來請看」中的影片播放位置。
- 應用程式會設定正確且完整的中繼資料。
新增未播放完畢的影片 - 電影和劇集之間的差異
將電影和劇集新增至「接下來請看」頻道的程序非常相似。唯一的差別是各個播放清單的中繼資料都不同。
例如,該集節目的 WatchNextProgram.Builder
中會有特定的中繼資料方法,例如 setEpisodeNumber, setSeasonNumber(),
、setSeasonTitle()
和 setEpisodeTitle()
將未看完的影片 (電影/劇集) 新增至「接下來請看」頻道
如要將未播放完畢的影片新增至「接下來請看」頻道,開發人員可以使用 WatchNextProgram.Builder
建立一個 WatchNextProgram
執行個體,並呼叫 PreviewChannelHelper.publishWatchNextProgram
以將該影片發布至「接下來請看」頻道。
首先,請建立 WatchNextProgram
的建構工具執行個體,並設定所有中繼資料來描述影片。
在 step_1 的 PlayNextHelper.kt
中搜尋 setBuilderMetadata
方法,然後將下列程式碼複製及貼上至「Step 1.1 - Set video metadata for WatchNextProgram.
」註解。
WatchNextHelper.kt
builder.setType(type)
.setWatchNextType(watchNextType)
.setLastPlaybackPositionMillis(watchPosition)
.setLastEngagementTimeUtcMillis(System.currentTimeMillis())
.setTitle(video.name)
.setDurationMillis(duration.toMillis().toInt())
.setPreviewVideoUri(Uri.parse(video.videoUri))
.setDescription(video.description)
.setPosterArtUri(Uri.parse(video.thumbnailUri))
// Intent uri used to deep link video when the user clicks on watch next item.
.setIntentUri(Uri.parse(video.uri))
.setInternalProviderId(video.id)
// Use the contentId to recognize the same content across different channels.
.setContentId(video.id)
if (type == TYPE_TV_EPISODE) {
builder.setEpisodeNumber(video.episodeNumber.toInt())
.setSeasonNumber(video.seasonNumber.toInt())
// User TV series name and season number to generate a fake season name.
.setSeasonTitle(context.getString(
R.string.season, video.category, video.seasonNumber))
// Use the name of the video as the episode name.
.setEpisodeTitle(video.name)
// Use TV series name as the tile, in this sample,
// we use category as a fake TV series.
.setTitle(video.category)
}
請詳閱步驟 1.1 的程式碼,嘗試瞭解為何要設定這些中繼資料。
setLastPlaybackPositionMillis()
和setDurationMillis()
會協助顯示正確的播放進度,並在使用者與影片互動時更新。setLastEngagementTimeUtcMillis()
會設定使用者觀看這部影片時的時間戳記,協助「接下來請看」頻道排定項目的優先順序。
將未看完的電影新增至「接下來請看」
我們可以運用 WATCH_NEXT_TYPE_NEXT
,將未看完的電影新增到「接下來請看」頻道。
設定電影的中繼資料:標題和描述
對於電影,請設定標題和描述以及其他屬性,以便使用者知道他們正在觀看正確的內容,而無需點閱影片。
builder.setType(type)
.setWatchNextType(watchNextType)
.setLastPlaybackPositionMillis(watchPosition)
.setLastEngagementTimeUtcMillis(System.currentTimeMillis())
.setTitle(video.name)
.setDurationMillis(duration.toMillis().toInt())
.setPreviewVideoUri(Uri.parse(video.videoUri))
.setDescription(video.description)
.setPosterArtUri(Uri.parse(video.thumbnailUri))
...
電影的螢幕截圖範例。
將未看完的劇集新增至「接下來請看」
有四種 類型 可用於 setWatchNextType()
,請使用 WATCH_NEXT_TYPE_CONTINUE
來播放未未觀看完畢的電視劇集,使用 WATCH_NEXT_TYPE_NEXT
來播放下一集。
設定該集節目的中繼資料:集數和季度編號/標題
對於電視劇集,請設定集數和季別編號,讓使用者無需點開影片,就知道他們正在觀看正確的劇集。
if (type == TYPE_TV_EPISODE) {
Builder.setType(PreviewPrograms.TYPE_EPISODE)
.setEpisodeNumber(video.episodeNumber.toInt())
.setSeasonNumber(video.seasonNumber.toInt())
// Use TV series name and season number to generate a fake season name.
.setSeasonTitle(context.getString(
R.string.season, video.category, video.seasonNumber))
// Use the name of the video as the episode name.
.setEpisodeTitle(video.name)
// Use TV series name as the tile, in this sample,
// we use category as a fake TV series.
.setTitle(video.category)
}
必須正確設定季度標題、劇集標題和標題。每個劇集都有描述該集內容的標題,可用來當做劇集標題。使用電視劇集標題作為電視節目標題的屬性,方便使用者瞭解劇集內容。如果您使用的是季別標題,可以將季別標題和季別編號合併使用,例如 <電視影集名稱> 季別 <季別編號>。
每一集節目的螢幕截圖範例。
繼續播放
setLastPlaybackPositionMillis(watchPosition)
可傳入使用者退出電影/劇集的時間,而進度將顯示在「接下來請看」資訊卡上。在電視的參考應用程式中,程式碼會使用 WatchProgressDatabase
追蹤每部影片的播放進度。如此一來,無論使用者如何瀏覽影片,都可以從上次停止的時間點繼續觀看影片。
根據《觀看動作播放指南》,該集節目內容會在影片載入後立即開始播放。使用者已開始觀看電視影集,因此不需要再次顯示相關資訊。
接著,請呼叫 PreviewChannelHelper.publishWatchNextProgram
,發布至「接下來請看」頻道。在同一個檔案中搜尋「Step 1.2
」,然後貼上以下程式碼:
WatchNextHelper.kt
try {
programId = PreviewChannelHelper(context)
.publishWatchNextProgram(updatedProgram)
Timber.v("Added New program to Watch Next row: ${updatedProgram.title}")
} catch (exc: IllegalArgumentException) {
Timber.e(
exc, "Unable to add program to Watch Next row. ${exc.localizedMessage}"
)
exc.printStackTrace()
}
重新整理播放進度
如果「接下來請看」頻道中已經存在「接下來請看」資訊卡,則應用程式需要在使用者觀看更多影片時保持更新,以反映最新的觀看進度。
更新 WatchNextProgram
時,請使用相同的建構工具類別建構 WatchNextProgram
,並呼叫 PreviewChannelHelper
的 updateWatchNextProgram
以更新現有條目。將下列程式碼貼入 WatchNextHelper.kt
中的「Step 1.3
」。
WatchNextHelper.kt
programId = existingProgram.id
PreviewChannelHelper(context).updateWatchNextProgram(updatedProgram, programId)
查看結果
檢查程式碼,找出您在「step_1_completed」中針對來源所做的變更,然後執行「step_1_completed」,並觀看該集節目的部分內容,確認該節目是否已新增至「接下來請看」頻道。
驗證
- ✅ 通過:節目暫停/停止播放後,就會新增至「接下來請看」
- ✅ 通過:應用程式可以從「接下來請看」條目繼續播放
- ✅ 通過:應用程式會即時更新「接下來請看」中的影片播放位置
- ✅ 通過:應用程式設定了正確且完整的中繼資料
- ✅ 通過:將所有未完成的內容推送到「接下來請看」
- ❗ 失敗:播放完畢後,系統會將節目從「接下來請看」中移除
- ❗ 失敗:在目前劇集結束時新增下一集
- ❗ 失敗:應用程式不會將使用者不曾互動的內容新增至「接下來請看」
- ❗ 失敗:應用程式不會新增同一電視影集的多個劇集
您已經瞭解的內容
在這個部分中,您已瞭解如何:
- 建立一個
WatchNextProgram
- 在「接下來請看」頻道中插入或更新 WatchNextProgram
- 更新播放進度
- 繼續播放
- 為電視劇集設定正確的中繼資料
後續步驟
將未看完的劇集新增至「接下來請看」頻道
5. 內容 (電影/劇集) 播放完畢後,將其從「接下來請看」中移除
「接下來請看」頻道的資訊卡會按照上次互動時間排序,最新的互動影片會顯示在頻道最前面。使用者看完節目後,應用程式應將節目從「接下來請看」頻道中移除,並向使用者宣傳更多相關內容。
開發人員必須監控影片的播放進度。使用者看完影片後,應用程式需從「接下來請看」頻道中移除影片。
注意:相同邏輯可用於移除「接下來請看」頻道中的電影或單集節目。
移除 WatchNextProgram
要從「接下來請看」頻道中移除條目,開發人員需要找到正確的「WatchNextProgram
」,並使用節目 URI 從內容供應者中刪除。為此,開發人員需將 WatchNextProgram
與自己資料庫中的影片實體進行配對。我們可以利用 internalProviderId 欄位設定專屬的影片 ID,然後將該 ID 連結至開發人員資料庫內的其中一個實體。
首先,透過尋找影片 ID 找出正確的 WatchNextProgram
。您可以透過 WatchNextProgram.
getInternalProviderId
或 WatchNextProgram
內容供應者存取 InternalProviderId,然後使用 URI 從「接下來請看」頻道中將其移除。
搜尋「Step 2.1
」並貼上下列內容:
WatchNextHelper.kt
val foundProgram = getWatchNextProgramByVideoId(video.id, context)
if (foundProgram == null) {
Timber.e(
"Unable to delete. No program found with videoID ${video.id}"
)
return null
}
// Use the found program's URI to delete it from the content resolver
return foundProgram.let {
val programUri = TvContractCompat.buildWatchNextProgramUri(it.id)
// delete returns the number of rows deleted.
val deleteCount = context.contentResolver.delete(
programUri, null, null
)
if (deleteCount == 1) {
Timber.v("Content successfully removed from Watch Next")
programUri
} else {
Timber.e("Content failed to be removed from Watch Next, delete count $deleteCount")
null
}
}
如要一次移除多個 WatchNextProgram
,建議要求批次作業,針對電視內容供應器的造訪進行最佳化。請搜尋「Step 2.2
」,然後將以下程式碼片段複製及貼上到 WatchNextHelper.kt
。
WatchNextHelper.kt
val foundPrograms = getWatchNextProgramByVideoIds(videos.map { it.id }, context)
val operations = foundPrograms.map {
val programUri = TvContractCompat.buildWatchNextProgramUri(it.id)
ContentProviderOperation.newDelete(programUri).build()
} as ArrayList<ContentProviderOperation>
val results = context.contentResolver.applyBatch(TvContractCompat.AUTHORITY, operations)
results.forEach { result ->
if (result.count != 1) {
Timber.e("Content failed to be removed from Watch Next: ${result.uri}")
}
}
根據「接下來請看」指南規定,如果使用者已看完劇集,則應移除該劇集。當片尾製作人員名單出現時,則視為使用者已「看完」劇集。在這種情況下,請勿將其新增到「接下來請看」頻道 (如果已新增,則將其移除)。如要判斷此狀態,您可以運用能自動偵測片尾製作人員名單的技術,或使用以內容長度為依據的近似值,例如劇集剩餘內容長度不到 3 分鐘。
您可以查看 WatchNextHelper.kt
中的 handleWatchNextForEpisodes()
方法,找到下列程式碼片段:
WatchNextHelper.kt
video.isAfterEndCreditsPosition(watchPosition.toLong()) -> {
removeVideoFromWatchNext(context, video)
...
}
在程式碼研究室中,我們使用 VIDEO_COMPLETED_DURATION_MAX_PERCENTAGE
模擬字幕後片段位置,您可以將 isAfterEndCreditsPosition()
中的程式碼取代為自己的邏輯。
查看結果
查看程式碼,並將您變更的內容與「step_2_completed」中的來源進行比較,然後執行「step_2_completed」並觀看該集節目,確認該集節目是否已在您觀看完畢後從「接下來請看」頻道中被移除。
驗證
- ✅ 通過:節目暫停/停止播放後,就會新增至「接下來請看」
- ✅ 通過:應用程式可以從「接下來請看」條目繼續播放
- ✅ 通過:應用程式會即時更新「接下來請看」中的影片播放位置
- ✅ 通過:應用程式設定了正確且完整的中繼資料
- ✅ 通過:將所有未完成的內容推送到「接下來請看」
- ✅ 通過:播放完畢後,系統會將節目從「接下來請看」中移除
- ❗ 失敗:在目前劇集結束時新增下一集
- ❗ 失敗:應用程式不會將使用者不曾互動的內容新增至「接下來請看」
- ❗ 失敗:應用程式不會新增同一電視影集的多個劇集
您已經瞭解的內容
在本簡介中,您瞭解了以下內容:
- 識別電視劇集的觀看場景
- 按照影片 ID 尋找
WatchNextProgram
- 刪除單一
WatchNextProgram
- 刪除多個
WatchNextProgram
後續步驟
將下一集新增至「接下來請看」頻道
6. 新增下一集
與電影不同,電視節目有超過 1 個季度,而且每個季度有很多集。如果使用者看完一個劇集,建議在「接下來請看」頻道中將該劇集替換為下一集,而不只是移除該劇集。下一集可以是同一季中剛看完劇集的下一集,或者,如果看完的劇集是目前季別的最後一集,則可以是下一季的第一集。
將下一集新增到「接下來請看」頻道時,只要將「接下來請看」類型設定為 WATCH_NEXT_TYPE_NEXT
,系統便會顯示該集節目並非先前看過的節目,而是使用者可以追蹤的全新一集。應用程式應允許使用者從頭開始觀看下一集。請搜尋「TODO: Step 3.1 - Add next episode from TV series.
」,然後將下列程式碼複製及貼上到步驟 3.1:
WatchNextHelper.kt
videoRepository.getNextEpisodeInSeries(video)?.let {
insertOrUpdateVideoToWatchNext(
it,
0,
WATCH_NEXT_TYPE_NEXT,
context
)
newWatchNextVideo = it
}
getNextEpisodeInSeries()
方法可擷取下一集節目。
同一季下一集
如果目前的季別仍有更多劇集,應用程式應選擇下一個可播放的劇集,並將其設為下一集。
下一季的第一集
如果使用者已經看完目前的季別,但有新的一季可觀看,則應用程式應選擇下一季的第一集做為下一集。
新集發布
如果沒有更多劇集,則應用程式無需新增下一集。但是,當有新劇集可提供觀賞時,最好將其推送到用戶端,並將其新增到「接下來請看」頻道。新的集數必須使用 WATCH_NEXT_TYPE_NEW
作為 WatchNextProgram 類型。此解決方案需要伺服器推播通知,但本程式碼研究室未涵蓋相關內容。
查看結果
瀏覽程式碼,將您的更改與「step_3_completed」中的來源進行比較,然後執行「step_3_completed」並觀看一集節目。當您觀看完畢,請確認下一集節目是否已新增至「接下來請看」頻道。
驗證
- ✅ 通過:節目暫停/停止播放後,就會新增至「接下來請看」
- ✅ 通過:應用程式可以從「接下來請看」條目繼續播放
- ✅ 通過:應用程式會即時更新「接下來請看」中的影片播放位置
- ✅ 通過:應用程式設定了正確且完整的中繼資料
- ✅ 通過:將所有未完成的內容推送到「接下來請看」
- ✅ 通過:播放完畢後,系統會將節目從「接下來請看」中移除
- ✅ 通過:在目前劇集結束時新增下一集
- ❗ 失敗:應用程式不會將使用者不曾互動的內容新增至「接下來請看」
- ❗ 失敗:應用程式不會新增同一電視影集的多個劇集
您已經瞭解的內容
在這個部分中,您已經瞭解到:
- 如何選取下一集
- 為電視影集新增下一集
後續步驟
瞭解使用者的興趣。
7. 瞭解使用者的興趣
為了讓使用者專注於「接下來請看」頻道中最相關的內容,在將電視劇集新增到「接下來請看」頻道或將其從頻道中移除時,應用程式需要考慮額外的注意事項。
同一系列的多個劇集
如果使用者在特定時間內有超過 1 個未看完的劇集,可能有多種原因。例如:
- 電視劇集可在多個應用程式或廣播中提供;
- 使用者想要加快速度並略過部分內容;
「接下來請看」頻道可顯示在主畫面上的項目非常有限,因此 Google 建議應用程式在「接下來請看」頻道中,最多只為每部電視影集保留一個劇集。左邊則應列出使用者上次觀看的劇集。
在 WatchNextHelper
類別中,我們會在 handlePlayNextForEpisode()
中處理。請搜尋「Step 4.1
」,然後將下列程式碼複製及貼上到步驟 4.1 的空白區域。
WatchNextHelper.kt
newWatchNextVideo?.let { videoToKeep ->
videoRepository.getAllVideosFromSeries(videoToKeep.seriesUri)?.let { allEpisodes ->
filterWatchNextVideos(allEpisodes, context)
?.let { watchedEpisodes ->
removeVideosFromWatchNext(
context, watchedEpisodes.filter { it.id != videoToKeep.id })
}
}
}
在步驟 4.1 中,我們持續追蹤使用者觀看的最新劇集,並移除同一電視影集中所有其他劇集。該步驟要一次刪除多個劇集,因此我們建立了新方法 removeVideosFromWatchNext()
,利用 Android 內容供應器進行批次作業。
互動較低的內容
根據「接下來請看」指南,只有在使用者已開始觀看時,才應將劇集新增到「接下來請看」頻道,而且在使用者已觀看超過 2 分鐘時,才視為使用者已「開始」觀看一集。請搜尋「Step 4.2
」,然後將以下程式碼複製及貼上到步驟 4.2 的區域。
WatchNextHelper.kt
val durationInMilliSeconds = duration.toMillis().toInt()
// Return true if either X minutes or Y % have passed
// Following formatting spans over multiple lines to accommodate max 100 limit
val watchNextMinStartedMillis = TimeUnit.MINUTES.toMillis(WATCH_NEXT_STARTED_MIN_MINUTES)
// Check if either X minutes or Y% has passed
val hasVideoStarted =
(currentPosition >= (durationInMilliSeconds * WATCH_NEXT_STARTED_MIN_PERCENTAGE)) or
(currentPosition >= watchNextMinStartedMillis)
val hasVideoStartedWithValidPosition =
((currentPosition <= durationInMilliSeconds) and hasVideoStarted)
Timber.v(
"Has video started: %s, duration: %s, watchPosition: %s",
hasVideoStartedWithValidPosition,
duration,
currentPosition
)
return hasVideoStartedWithValidPosition
查看結果
請瀏覽程式碼,比較您的變更與 step_4_completed 中的原始碼,接著執行 step_4_completed 並觀看一個劇集,確認下列事項:
- 程式碼會移除電視影集中的額外劇集
- 只有在使用者開始觀看後,內容才會新增至「接下來請看」頻道
驗證
- ✅ 通過:節目暫停/停止播放後,就會新增至「接下來請看」
- ✅ 通過:應用程式可以從「接下來請看」條目繼續播放
- ✅ 通過:應用程式會即時更新「接下來請看」中的影片播放位置
- ✅ 通過:應用程式設定了正確且完整的中繼資料
- ✅ 通過:將所有未完成的內容推送到「接下來請看」
- ✅ 通過:播放完畢後,系統會將節目從「接下來請看」中移除
- ✅ 通過:在目前劇集結束時新增下一集
- ✅ 通過:應用程式不會將使用者不曾互動的內容新增至「接下來請看」
- ✅ 通過:應用程式不會新增同一電視影集中的多個劇集
您已經瞭解的內容
在這個部分中,您已經瞭解到:
- 避免新增同一電視影集的多個劇集
- 避免新增缺乏互動的內容
後續步驟
恭喜
8. 恭喜
恭喜!您成功為電視劇集建立「接下來請看」,並瞭解「接下來請看」的所有品質規定。
太棒了!