กำลังฟังเหตุการณ์การเล่น
เหตุการณ์ เช่น การเปลี่ยนแปลงสถานะและข้อผิดพลาดในการเล่น จะได้รับการรายงานไปยัง
Player.Listener
อินสแตนซ์ หากต้องการลงทะเบียนผู้ฟังเพื่อรับ
กิจกรรม:
Kotlin
// Add a listener to receive events from the player. player.addListener(listener)
Java
// Add a listener to receive events from the player. player.addListener(listener);
Player.Listener
ไม่มีเมธอดเริ่มต้น คุณจึงต้องติดตั้งใช้งาน
วิธีการที่คุณสนใจ โปรดดู Javadoc สำหรับคำอธิบายแบบเต็มของ
เมธอดและเวลาที่เรียกใช้ วิธีการที่สำคัญที่สุดส่วนหนึ่ง ได้แก่
ตามที่อธิบายไว้โดยละเอียดด้านล่าง
ผู้ฟังมีตัวเลือกระหว่างการติดตั้งใช้งาน Callback เหตุการณ์แต่ละรายการหรือ
Callback ทั่วไปของ onEvents
ที่เรียกใช้หลังจากเกิดเหตุการณ์อย่างน้อย 1 เหตุการณ์
ดู Individual callbacks vs onEvents
สำหรับคำอธิบายเกี่ยวกับ
สำหรับกรณีการใช้งานที่แตกต่างกัน
การเปลี่ยนแปลงสถานะการเล่น
คุณสามารถรับการเปลี่ยนแปลงสถานะโปรแกรมเล่นวิดีโอได้โดยใช้
onPlaybackStateChanged(@State int state)
ใน
Player.Listener
โดยโปรแกรมเล่นอาจอยู่ในสถานะการเล่นใดสถานะหนึ่งจาก 4 สถานะต่อไปนี้
Player.STATE_IDLE
: นี่คือสถานะเริ่มต้น หรือสถานะเมื่อโปรแกรมเล่นวิดีโออยู่ และเมื่อการเล่นล้มเหลว โปรแกรมเล่นนี้จะมีทรัพยากรจำกัดเท่านั้น ในสถานะนี้Player.STATE_BUFFERING
: โปรแกรมเล่นจะไม่สามารถเล่นจากโปรแกรมเล่นได้ทันที ตำแหน่งปัจจุบัน ปัญหานี้มักเกิดขึ้นเพราะต้องโหลดข้อมูลเพิ่มPlayer.STATE_READY
: โปรแกรมเล่นนี้จะเล่นจากสตรีมปัจจุบันได้ทันที ตำแหน่งPlayer.STATE_ENDED
: โปรแกรมเล่นเล่นสื่อทั้งหมดเสร็จแล้ว
นอกจากรัฐเหล่านี้แล้ว ผู้เล่นยังมีธง playWhenReady
เพื่อระบุ
ที่ผู้ใช้ตั้งใจที่จะเล่น การเปลี่ยนแปลงใน Flag นี้สามารถรับได้โดยใช้การติดตั้งใช้งาน
onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)
โปรแกรมเล่นวิดีโอกำลังเล่น (กล่าวคือ ตำแหน่งของผู้เล่นคือความคืบหน้า และสื่อยังคงเล่นอยู่ แสดงแก่ผู้ใช้) เมื่อเป็นไปตามเงื่อนไขทั้ง 3 ข้อต่อไปนี้
- โปรแกรมเล่นอยู่ในสถานะ
Player.STATE_READY
playWhenReady
true
- ไม่ได้ระงับการเล่นด้วยเหตุผลที่แสดงผลโดย
Player.getPlaybackSuppressionReason
แทนที่จะต้องตรวจสอบคุณสมบัติเหล่านี้ทีละรายการ Player.isPlaying
จะสามารถโทรออกได้ รับการเปลี่ยนแปลงสถานะนี้ได้โดยใช้
onIsPlayingChanged(boolean isPlaying)
:
Kotlin
player.addListener( object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.playWhenReady, // player.playbackState, player.playbackSuppressionReason and // player.playerError for details. } } } )
Java
player.addListener( new Player.Listener() { @Override public void onIsPlayingChanged(boolean isPlaying) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.getPlayWhenReady, // player.getPlaybackState, player.getPlaybackSuppressionReason and // player.getPlaybackError for details. } } });
ข้อผิดพลาดในการเล่น
คุณสามารถแก้ไขข้อผิดพลาดที่ทำให้การเล่นไม่สำเร็จโดยใช้
onPlayerError(PlaybackException error)
ใน
Player.Listener
เมื่อเกิดข้อผิดพลาด ระบบจะเรียกใช้เมธอดนี้
ก่อนที่สถานะการเล่นจะเปลี่ยนเป็น Player.STATE_IDLE
คุณลองเล่นที่ไม่สำเร็จหรือหยุดได้อีกโดยโทรหา ExoPlayer.prepare
โปรดทราบว่าการติดตั้งใช้งาน Player
บางรายการผ่านอินสแตนซ์ของคลาสย่อยของ
PlaybackException
เพื่อระบุข้อมูลเพิ่มเติมเกี่ยวกับความล้มเหลว สำหรับ
เช่น ExoPlayer
ส่ง ExoPlaybackException
ซึ่งมี type
rendererIndex
และช่องอื่นๆ สำหรับ ExoPlayer โดยเฉพาะ
ตัวอย่างต่อไปนี้แสดงวิธีตรวจสอบว่าเล่นไม่สำเร็จเนื่องจาก ปัญหาเกี่ยวกับเครือข่าย HTTP:
Kotlin
player.addListener( object : Player.Listener { override fun onPlayerError(error: PlaybackException) { val cause = error.cause if (cause is HttpDataSourceException) { // An HTTP error occurred. val httpError = cause // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError is InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } } )
Java
player.addListener( new Player.Listener() { @Override public void onPlayerError(PlaybackException error) { @Nullable Throwable cause = error.getCause(); if (cause instanceof HttpDataSourceException) { // An HTTP error occurred. HttpDataSourceException httpError = (HttpDataSourceException) cause; // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError instanceof HttpDataSource.InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } });
การเปลี่ยนเพลย์ลิสต์
ทุกครั้งที่โปรแกรมเล่นเปลี่ยนเป็นรายการสื่อใหม่ในเพลย์ลิสต์
onMediaItemTransition(MediaItem mediaItem,
@MediaItemTransitionReason int reason)
เรียกใช้เมื่อลงทะเบียน
Player.Listener
ออบเจ็กต์ เหตุผลระบุว่านี่เป็นการดำเนินการอัตโนมัติ
การเปลี่ยน การกรอ (ตัวอย่างเช่น หลังจากเรียก player.next()
) การกล่าวซ้ำๆ
รายการเดียวกันหรือเกิดจากการเปลี่ยนแปลงเพลย์ลิสต์ (เช่น หาก
รายการที่กำลังเล่นถูกนำออก)
ข้อมูลเมตา
ข้อมูลเมตาที่แสดงผลจาก player.getCurrentMediaMetadata()
อาจมีการเปลี่ยนแปลงเนื่องจาก
เหตุผล: การเปลี่ยนเพลย์ลิสต์ การอัปเดตข้อมูลเมตาในสตรีม หรือการอัปเดต
การเล่นMediaItem
ตรงกลางปัจจุบัน
หากคุณต้องการเปลี่ยนแปลงข้อมูลเมตา เช่น เพื่ออัปเดต UI ที่แสดง
เพลงปัจจุบัน คุณสามารถฟัง onMediaMetadataChanged
ได้
กำลังค้นหา
การเรียกใช้ Player.seekTo
วิธีจะทําให้เกิดการติดต่อกลับหลายครั้งเพื่อลงทะเบียน
อินสแตนซ์ Player.Listener
รายการ:
onPositionDiscontinuity
ด้วยreason=DISCONTINUITY_REASON_SEEK
นี่คือ ผลลัพธ์โดยตรงจากการโทรหาPlayer.seekTo
การติดต่อกลับมีPositionInfo
สำหรับตำแหน่งก่อนและหลังการกรอonPlaybackStateChanged
โดยมีการเปลี่ยนแปลงสถานะในทันทีที่เกี่ยวข้องกับการค้นหา โปรดทราบว่าอาจไม่มีการเปลี่ยนแปลงดังกล่าว
การเรียกกลับแต่ละรายการเทียบกับ onEvents
ผู้ฟังสามารถเลือกระหว่างการติดตั้งใช้งาน Callback แต่ละรายการ เช่น
onIsPlayingChanged(boolean isPlaying)
และข้อกำหนดทั่วไป
onEvents(Player player, Events events)
Callback Callback ทั่วไปจะให้
สิทธิ์เข้าถึงออบเจ็กต์ Player
และระบุชุดของ events
ที่เกิดขึ้น
Callback นี้จะถูกเรียกหลังจาก Callback ที่สอดคล้องกับ
แต่ละเหตุการณ์
Kotlin
override fun onEvents(player: Player, events: Player.Events) { if ( events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED) ) { uiModule.updateUi(player) } }
Java
@Override public void onEvents(Player player, Events events) { if (events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)) { uiModule.updateUi(player); } }
ควรเลือกใช้เหตุการณ์แต่ละรายการในกรณีต่อไปนี้
- ผู้ฟังสนใจเหตุผลในการเปลี่ยนแปลง ตัวอย่างเช่น พารามิเตอร์
ระบุเหตุผลสำหรับ
onPlayWhenReadyChanged
หรือonMediaItemTransition
- Listener จะดำเนินการกับค่าใหม่ที่ระบุผ่านพารามิเตอร์ Callback เท่านั้น หรือทริกเกอร์อย่างอื่นที่ไม่ได้ขึ้นอยู่กับพารามิเตอร์ Callback
- การใช้งาน Listener ต้องการตัวบ่งชี้ที่อ่านได้ชัดเจนว่า ทริกเกอร์เหตุการณ์ในชื่อเมธอด
- ผู้ฟังรายงานไปยังระบบข้อมูลวิเคราะห์ที่จำเป็นต้องทราบ แต่ละเหตุการณ์และการเปลี่ยนแปลงสถานะ
ควรใช้ onEvents(Player player, Events events)
ทั่วไปใน
กรณีต่อไปนี้
- Listener ต้องการทริกเกอร์ตรรกะเดียวกันสำหรับหลายเหตุการณ์ สำหรับ
ตัวอย่างเช่น การอัปเดต UI สำหรับทั้ง
onPlaybackStateChanged
และonPlayWhenReadyChanged
- Listener ต้องการสิทธิ์เข้าถึงออบเจ็กต์
Player
เพื่อทริกเกอร์เหตุการณ์เพิ่มเติม ตัวอย่างเช่น การกรอวิดีโอ หลังการเปลี่ยนรายการสื่อ - Listener ต้องการใช้ค่าสถานะหลายค่าที่มีการรายงาน
ผ่าน Callback แยกต่างหากรวมกัน หรือใช้ร่วมกับ Getter ของ
Player
ตัวอย่างเช่น การใช้Player.getCurrentWindowIndex()
กับแท็กTimeline
ที่ให้ไว้ในonTimelineChanged
ปลอดภัยจากภายใน การติดต่อกลับonEvents
- ผู้ฟังต้องการทราบว่าเหตุการณ์ต่างๆ เกิดขึ้นพร้อมกันอย่างสมเหตุสมผลหรือไม่ สำหรับ
ตัวอย่างเช่น
onPlaybackStateChanged
ถึงSTATE_BUFFERING
เนื่องจากรายการสื่อ การเปลี่ยนแปลง
ในบางกรณี ผู้ฟังอาจต้องรวมการเรียกกลับแต่ละรายการเข้ากับ
Callback ทั่วไปของ onEvents
เช่น เพื่อบันทึกเหตุผลที่เปลี่ยนแปลงรายการสื่อ
กับ onMediaItemTransition
แต่จะดำเนินการเมื่อสามารถเปลี่ยนสถานะทั้งหมดได้แล้วเท่านั้น
ร่วมกันใน onEvents
กำลังใช้ AnalyticsListener
เมื่อใช้ ExoPlayer
คุณจะลงทะเบียน AnalyticsListener
กับโปรแกรมเล่นได้
โดยโทรไปที่ addAnalyticsListener
การติดตั้งใช้งาน AnalyticsListener
รายการได้
เพื่อฟังเหตุการณ์โดยละเอียดที่อาจเป็นประโยชน์สำหรับข้อมูลวิเคราะห์และการบันทึก
วัตถุประสงค์ โปรดดูรายละเอียดเพิ่มเติมในหน้าข้อมูลวิเคราะห์
กำลังใช้ EventLogger
EventLogger
เป็นAnalyticsListener
ที่ห้องสมุดดนตรีโดยตรงสำหรับ
วัตถุประสงค์ของการบันทึก เพิ่ม EventLogger
ไปยัง ExoPlayer
เพื่อเปิดใช้
การบันทึกเพิ่มเติมด้วยบรรทัดเดียว:
Kotlin
player.addAnalyticsListener(EventLogger())
Java
player.addAnalyticsListener(new EventLogger());
ดูรายละเอียดเพิ่มเติมได้ที่หน้าบันทึกการแก้ไขข้อบกพร่อง
การเริ่มทำงานที่ตำแหน่งการเล่นที่ระบุ
กรณีการใช้งานบางอย่างต้องการให้เหตุการณ์การเริ่มทำงานที่ตำแหน่งการเล่นที่ระบุ นี่คือ
สนับสนุนโดยใช้ PlayerMessage
PlayerMessage
สามารถสร้างขึ้นได้โดยใช้
ExoPlayer.createMessage
ตำแหน่งการเล่นที่ควรจะดำเนินการ
ตั้งค่าได้โดยใช้ PlayerMessage.setPosition
ข้อความจะดำเนินการใน
เทรดการเล่นตามค่าเริ่มต้น แต่สามารถปรับแต่งได้โดยใช้
PlayerMessage.setLooper
คุณใช้ PlayerMessage.setDeleteAfterDelivery
ได้
เพื่อควบคุมว่าจะเรียกใช้ข้อความทุกครั้งที่
พบตำแหน่งการเล่น (ซึ่งอาจเกิดขึ้นได้หลายครั้งเนื่องจากการกรอวิดีโอ
และโหมดซ้ำ) หรือแค่ครั้งแรก เมื่อ PlayerMessage
คือ
กำหนดค่าแล้ว ก็สามารถกำหนดเวลาโดยใช้ PlayerMessage.send
Kotlin
player .createMessage { messageType: Int, payload: Any? -> } .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send()
Java
player .createMessage( (messageType, payload) -> { // Do something at the specified playback position. }) .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120_000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send();