项目作者: Cuento3yLlevo2

项目描述 :
VideoLytics is a custom Analytics Collector for ExoPlayer events during Video Playback.
高级语言: Kotlin
项目地址: git://github.com/Cuento3yLlevo2/VideoLytics-Framework.git
创建时间: 2021-07-02T06:51:51Z
项目社区:https://github.com/Cuento3yLlevo2/VideoLytics-Framework

开源协议:

下载


VideoLytics

VideoLytics is a custom Analytics Collector for ExoPlayer events during Video Playback.

VideoLytics demo gif

  • Counts how many times a video is paused during playback
  • Counts how many times a video is resumed/restarted.
  • Tracks the time elapsed between every pause and resume event.
  • Provides data collected modified in real time to display on Activity.
  • Makes HTTP POST requests to https://jsonplaceholder.typicode.com/ with JSON Object with data collected.

VideoLytics Repository

This repository contains a test application with one activity using ExoPlayer for reproducing video and the VideoLytics Framework module as a dependency library.

1. Installing The VideoLytics Framework

To install the VideoLytics Framework, simply download the zip file (using the Clone or download option on GitHub) and import only the VideoLyticsFramework module into your existing Android Studio project.

  • Choose File > New > Import Module.
  • Select the VideoLyticsFramework folder.
  • Add the following line to your app-level build.gradle file:
  1. implementation project(':VideoLyticsFramework')

If not implemented already, you also need to Add ExoPlayer module dependencies and use ExoPlayer to reproduce the video content instead of Android’s MediaPlayer.

VideoLytics Framework does not support Android’s MediaPlayer yet.

2. Using the VideoLytics Framework

Add an AnalyticsDataListener Interface to the activity or fragment that contains the ExoPlayer Instance

  1. class VideoLyticsDemoActivity : AppCompatActivity(), AnalyticsDataListener {
  2. override fun onCreate(savedInstanceState: Bundle?) {...}
  3. // implement its members
  4. override fun onAnalyticsDataChanged(dataType: Int) {
  5. ...
  6. }
  7. override fun onVideoFinished() {
  8. ...
  9. }
  10. }

Create a VideoLytics class instance which will pass as parameters the current context and the AnalyticsDataListener Interface.

  1. private lateinit var videoLytics : VideoLytics
  2. private var exoplayer: SimpleExoPlayer? = null
  3. override fun onCreate(savedInstanceState: Bundle?) {
  4. super.onCreate(savedInstanceState)
  5. setContentView(R.layout.activity_video_lytics_demo)
  6. videoLytics = VideoLytics(
  7. this /* context */,
  8. this /* AnalyticsDataListener */)
  9. // Initialize Exoplayer after that
  10. initExoplayer()
  11. }

The VideoLytics Framework collects data using the VideoLyticsListener class that extends from ExoPlayer’s AnalyticsListener Interface. This interface listens for the Raw playback events from a given player.

After creating the ExoPlayer instance you should add VideoLyticsListener class as an AnalyticsListener with the method videoLytics.initCollector() that returns a VideoLyticsListener instance.

  1. private fun initExoplayer() {
  2. // create an ExoPlayer instance
  3. exoplayer = SimpleExoPlayer.Builder(this).build()
  4. // Adding VideoLyticsListener as AnalyticsListener
  5. exoplayer?.addAnalyticsListener(
  6. VideoLyticsListener(
  7. videoLytics.initCollector()
  8. )
  9. )
  10. }

All data collected is available from your application’s Activity or Fragment by retrieving data from the videoLytics.analyticsData class.

Use the AnalyticsDataListener interface implemented methods to listen for updates on videoLytics.analyticsData class to retrieve changes in real time.

  1. override fun onAnalyticsDataChanged(dataType: Int) {
  2. when(dataType){
  3. VideoLytics.TIMES_PAUSED_CHANGED -> {
  4. val totalTimesPausedString = "Paused: ${videoLytics.analyticsData.totalTimesPaused} times"
  5. tvTotalTimesPaused.text = totalTimesPausedString
  6. }
  7. VideoLytics.TIMES_RESUMED_CHANGED -> {
  8. val totalTimesResumedString = "Resumed: ${videoLytics.analyticsData.totalTimesResumed} times"
  9. val timeElapsedString = "Time Elapsed: ${videoLytics.analyticsData.timeElapsedUntilResumedAgain?.div(1000.0)} secs"
  10. tvTotalTimesResumed.text = totalTimesResumedString
  11. tvTimeElapsed.text = timeElapsedString
  12. }
  13. }
  14. }
  15. override fun onVideoFinished() {
  16. videoFinishedLayoutRoot.visibility = View.VISIBLE
  17. val totalTimesPausedString = "Number of times Paused: ${videoLytics.analyticsData.totalTimesPaused} times"
  18. val totalTimesResumedString = "Number of times Resumed: ${videoLytics.analyticsData.totalTimesResumed} times"
  19. tvVideoFinishedTotalTimesPaused.text = totalTimesPausedString
  20. tvVideoFinishedTotalTimesResumed.text = totalTimesResumedString
  21. videoLytics.analyticsData.resumedTimeElapsedList.forEachIndexed { index, timeElapsedMilisecs ->
  22. var content = ""
  23. content += "${timeElapsedMilisecs.div(1000.0)} secs Elapsed Until Resumed Nº ${index+1}\n"
  24. tvVideoFinishedTimeElapsedList.append(content)
  25. }
  26. }

onAnalyticsDataChanged: listens for:

  • Number of times Paused changes VideoLytics.TIMES_PAUSED_CHANGED.
  • Number of times Resumed changes VideoLytics.TIMES_RESUMED_CHANGED.

onVideoFinished(): listens when the video playback finished.

3. About HTTP POST requests fake API for testing

The VideoLytics Framework uses Volley HTTP library to make a fake HTTP POST request to https://jsonplaceholder.typicode.com/ for testing purposes every time that:

  • Video starts to load(first play only) —> (Json Request Body Example)
    1. {"dataLastUpdateTimeMs":1059924668,"dataLastUpdateType":"FIRST_LOAD","firstLoadTimeMs":1059924668,"totalTimesPaused":0,"totalTimesResumed":0,"videoPosition":0,"videoUriPath":"http://yourvideosrc"}
  • Video shows up its first frame —> (Json Request Body Example)
    1. {"dataLastUpdateTimeMs":1059926784,"dataLastUpdateType":"RENDERED_FRAME","firstLoadTimeMs":1059924668,"renderedFrameTimeMs":1059926784,"totalTimesPaused":0,"totalTimesResumed":0,"videoPosition":0,"videoUriPath":"yourvideosrc"}
  • Video has been stopped. —> (Json Request Body Example)
    1. {"dataLastUpdateTimeMs":1060023857,"dataLastUpdateType":"VIDEO_STOPPED","firstLoadTimeMs":1059924668,"renderedFrameTimeMs":1059926784,"timeElapsedUntilResumedAgain":870,"totalTimesPaused":4,"totalTimesResumed":3,"videoPosition":91099,"videoUriPath":"yourvideosrc8"}
  • Video is finished. —> (Json Request Body Example)
    1. {"dataLastUpdateTimeMs":1060110600,"dataLastUpdateType":"VIDEO_FINISHED","firstLoadTimeMs":1059924668,"renderedFrameTimeMs":1060033828,"timeElapsedUntilResumedAgain":214,"totalTimesPaused":9,"totalTimesResumed":9,"videoFinishedTimeMs":1060110600,"videoPosition":5365002,"videoUriPath":"yourvideosrc"}

4. External Dependencies

The VideoLytics Framework uses in its module the following external dependencies:

  1. // An extensible media player for Android (Only Core Module)
  2. implementation 'com.google.android.exoplayer:exoplayer-core:2.14.1'
  3. // Volley HTTP library
  4. implementation 'com.android.volley:volley:1.2.0'
  5. // Library to convert Java Objects into JSON and back
  6. implementation 'com.google.code.gson:gson:2.8.7'