เราจะเพิ่ม Visualizer ใน ExoPlayer ยังไงดีนะ?
มันไม่ได้ใช้ง่ายเท่าตอนใส่ใน MediaPlayer อ่ะดิ
อันนี้เราลองเขียนขึ้นมาเล่นๆ ว่าถ้าเราเล่นไฟล์เสียงใน ExoPlayer แล้ว มีเจ้า Visualizer มาด้วย เอ้อออ ว่าแต่ ทำยังไงนะ
ก่อนอื่นมาลองอ่านมาลองทำตามบล็อกนี้ก่อนนะ เดี๋ยวจะอธิบายให้ฟัง
ส่วนประกอบหลักๆมี 2 ส่วน คือ Visualizer View และ Player บน Activity/Fragment
Visualizer View ขอเล่าคร่าวๆว่ามันเป็น View Class ตัวนึง ที่แสดง Visualizer ของไฟล์เสียงของเรา ซึ่งอาจจะเขียนเองแบบในบล็อกอ้างอิงด้านบน จะเป็นแบบเส้นๆ หรือใช้ library ก็ได้นะ เลือกได้ว่าอยากออกมาแบบไหน ไม่ต้องวาดเอง เช่น
ส่วน Player ในหน้า Activity/Fragment ที่เราต้องการ ก็ต้องมีเจ้า ExoPlayer อยู่ในนี้ก่อนเนอะ ซึ่งเจ้า ExoPlayer จะแยกเป็น 2 ส่วน คือ View และ Player
ก่อนอื่นแจ้งกันก่อน เราใช้ ExoPlayer version นี้นะ
implementation 'com.google.android.exoplayer:exoplayer:2.10.4'
ซึ่งส่วนของ ExoPlayer View นั้นเราใส่ลงไปใน layout ซึ่งใส่แบบ basic ก่อนค่อยมา custom ทีหลังแล้วกัน โดยเราจะให้เจ้า Visualizer View ไว้ด้านบน Player เพื่อ UX ที่ดี เป็นธรรมชาติ
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.gauravk.audiovisualizer.visualizer.BlastVisualizer
android:id="@+id/playerVisualizer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:avDensity="0.8"
app:avType="fill"
app:avColor="@color/av_dark_blue"
app:avSpeed="normal"/>
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/playerView"
android:layout_width="match_parent"
android:layout_height="100dp" />
</LinearLayout>
เรามาสร้างเจ้า player ของ ExoPlayer กันเถอะ พร้อมกำหนดค่าต่างๆใน player ของเรา
และก็สร้าง Visualizer ขึ้นมา และนำมาเล่น
ใน listener ของ Visualizer.OnDataCaptureListener
เราจะต้อง override 2 functions ด้วยกัน
onWaveFormDataCapture
อันนี้เราจะได้เจ้า waveform ออกมาonFftDataCapture
อันนี้เราจะได้ fft (ใน doc บอกว่า frequency capture) ออกมา
ทั้ง waveform และ fft นั้น จะเป็น ByteArray ทั้งคู่
Visualizer.OnDataCaptureListener | Android Developers
AccessibilityService.MagnificationController.OnMagnificationChangedListenerdeveloper.android.com
จริงๆเจ้า visualizer.setDataCaptureListener นั้น parameter แรกนั้นใส่เจ้า object ของ Visualizer.OnDataCaptureListener เพื่อ implement data capture ว่าเอาไปทำอะไรต่อ ถ้าให้แสดงแบบ waveform หรือ fft จากนั้น parameter ต่อมาเป็นค่า rate ส่วนสอง parameter หลังนั้น เป็นการ enable ว่าจะใช้แบบ waveform หรือ fft ดี ซึ่งเราขอแนะนำควรใส่ค่า true แค่อันไหนอันนึงพอจ้า ถ้า false ทั้งคู่มันจะไม่ขึ้นนะเตง ถ้าใส่ true สองอันเราจะเห็น fft เป็นหลักอ่ะ การฟมันใหญ่บัง waveform มิดเชียว
แต่แล้วความแตกต่างจาก MediaPlayer คือ exoPlayer.audioSessionId
ดันเป็น 0 ซะได้ และ crash ตลอดเลย
ลองมา google กันหน่อย ทำยังไงให้ได้ค่านี้มามากกว่า 0 จนมาเจออันนี้ เราต้อง get audioSessionId จาก AnalyticsListener
exoPlayer.addAnalyticsListener(object : AnalyticsListener {
override fun onAudioSessionId(
eventTime: AnalyticsListener.EventTime?,
audioSessionId: Int
) {
startPlayerVisualizer(audioSessionId)
}
})
เรารับ audioSessionId จากในนี้ ค่ามันก็มากกว่า 0 แล้วหล่ะถ้าลอง debug ดูอะนะ และพอเอาไปรันสุดท้ายได้ผลเหมือน MediaPlayer แล้ว เย้ๆๆๆๆ
สรุปโค้ดทั้งหมดเลยดีกว่า
แต่อัดวิดีโอเดโม่ลำบากมาก เพราะอัดจากโทรศัพท์ก็ไม่ได้ เหมือนอัดเสียงในอัดเสียงอีกที โอ้ยยยย สับสน
สุดท้ายเราปรับให้เจ้า ExoPlayer ของเรา เป็นเนื้อเดียวกับ Visualizer ให้มากกว่านี้หน่อย ซึ่งเราก็ custom player มาอีกทีนึง
เดี๋ยวหาว่าจบไวไป ขอเล่าเรื่อง custom player สั้นๆ จ้า
ก่อนอื่นเพิ่มเจ้า ExoPlayer เข้าไปใน layout ของเราก่อน
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="@+id/playerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:controller_layout_id="@layout/layout_player"
app:use_controller="true"
app:auto_show="true"
app:show_timeout="0"
app:hide_on_touch="false" />
- เราใส่ layout player ที่เรา custom ลงไปใน
app:controller_layout_id
- ส่วนอันนี้เราใส่ไปเพื่อไม่ให้ player มัน hide ตัวเอง
app:use_controller="true"
app:auto_show="true"
app:show_timeout="0"
- และใส่อันนี้ไปอีกที เพื่อบอกว่า ถ้ามือเราไปโดน player แล้วไม่ต้อง hide เน้อ
app:hide_on_touch="false"
จากนั้นเราก็สร้าง layout custom player ขึ้นมา นามว่า layout_player.xml
ซึ่งเราต้อง override ปุ่ม โดยเรา override id ของปุ่มต่างๆ เช่น ปุ่มเล่น override @+id/exo_play
ปุ่มหยุด override @+id/exo_pause
ประมาณนี้
หรืออ่านเพิ่มเติมที่นี่
สุดท้ายฝากร้านกันสักนิด ฝากเพจด้วยนะจ๊ะ