Analytics

ExoPlayer প্লেব্যাক বিশ্লেষণের চাহিদার বিস্তৃত পরিসরকে সমর্থন করে। শেষ পর্যন্ত, বিশ্লেষণ হল প্লেব্যাক থেকে ডেটা সংগ্রহ, ব্যাখ্যা করা, একত্রিত করা এবং সংক্ষিপ্ত করা। এই ডেটা ডিভাইসে ব্যবহার করা যেতে পারে-উদাহরণস্বরূপ লগিং, ডিবাগিং, বা ভবিষ্যতে প্লেব্যাকের সিদ্ধান্ত জানানোর জন্য-অথবা সমস্ত ডিভাইস জুড়ে প্লেব্যাক নিরীক্ষণ করার জন্য সার্ভারে রিপোর্ট করা যেতে পারে।

একটি অ্যানালিটিক্স সিস্টেমকে সাধারণত প্রথমে ইভেন্টগুলি সংগ্রহ করতে হয় এবং তারপরে সেগুলিকে অর্থবহ করতে আরও প্রক্রিয়া করতে হয়:

  • ইভেন্ট সংগ্রহ : এটি একটি ExoPlayer দৃষ্টান্তে একটি AnalyticsListener নিবন্ধন করে করা যেতে পারে। রেজিস্টার করা অ্যানালিটিক্স শ্রোতারা প্লেয়ার ব্যবহারের সময় ইভেন্টগুলি গ্রহণ করে। প্রতিটি ইভেন্ট প্লেলিস্টে সংশ্লিষ্ট মিডিয়া আইটেম, সেইসাথে প্লেব্যাক অবস্থান এবং টাইমস্ট্যাম্প মেটাডেটার সাথে যুক্ত।
  • ইভেন্ট প্রসেসিং : কিছু অ্যানালিটিক্স সিস্টেম একটি সার্ভারে কাঁচা ইভেন্ট আপলোড করে, সমস্ত ইভেন্ট প্রসেসিং সার্ভার-সাইডে সঞ্চালিত হয়। ডিভাইসে ইভেন্টগুলি প্রক্রিয়া করাও সম্ভব, এবং এটি করা সহজ হতে পারে বা আপলোড করা প্রয়োজন এমন তথ্যের পরিমাণ হ্রাস করতে পারে। ExoPlayer PlaybackStatsListener প্রদান করে, যা আপনাকে নিম্নলিখিত প্রক্রিয়াকরণ পদক্ষেপগুলি সম্পাদন করতে দেয়:
    1. ইভেন্ট ব্যাখ্যা : বিশ্লেষণের উদ্দেশ্যে উপযোগী হতে, একটি একক প্লেব্যাকের প্রসঙ্গে ইভেন্টগুলিকে ব্যাখ্যা করতে হবে। উদাহরণস্বরূপ STATE_BUFFERING এ প্লেয়ার স্টেট পরিবর্তনের অশোধিত ঘটনা প্রাথমিক বাফারিং, রিবাফার বা বাফারিংয়ের সাথে মিলে যেতে পারে যা একটি অনুসন্ধানের পরে ঘটে।
    2. স্টেট ট্র্যাকিং : এই ধাপটি ইভেন্টকে কাউন্টারে রূপান্তর করে। উদাহরণস্বরূপ, প্রতিটি প্লেব্যাক অবস্থায় কতটা সময় ব্যয় করা হয়েছে তা ট্র্যাক করে স্টেট পরিবর্তন ইভেন্টগুলিকে কাউন্টারে রূপান্তরিত করা যেতে পারে। ফলাফল হল একটি একক প্লেব্যাকের জন্য বিশ্লেষণ ডেটা মানগুলির একটি মৌলিক সেট৷
    3. একত্রীকরণ : এই ধাপটি একাধিক প্লেব্যাক জুড়ে বিশ্লেষণ ডেটা একত্রিত করে, সাধারণত কাউন্টার যোগ করে।
    4. সারাংশ মেট্রিক্সের গণনা : অনেকগুলি দরকারী মেট্রিক হল যেগুলি গড় গণনা করে বা অন্যান্য উপায়ে মৌলিক বিশ্লেষণ ডেটা মানগুলিকে একত্রিত করে। সারাংশ মেট্রিক্স একক বা একাধিক প্লেব্যাকের জন্য গণনা করা যেতে পারে।

অ্যানালিটিক্সলিসনার সাথে ইভেন্ট সংগ্রহ

প্লেয়ার থেকে অশোধিত প্লেব্যাক ইভেন্টগুলি AnalyticsListener বাস্তবায়নে রিপোর্ট করা হয়। আপনি সহজেই আপনার নিজের শ্রোতা যোগ করতে পারেন এবং শুধুমাত্র আপনার আগ্রহের পদ্ধতিগুলিকে ওভাররাইড করতে পারেন:

কোটলিন

exoPlayer.addAnalyticsListener(
  object : AnalyticsListener {
    override fun onPlaybackStateChanged(
      eventTime: EventTime, @Player.State state: Int
    ) {}

    override fun onDroppedVideoFrames(
      eventTime: EventTime,
      droppedFrames: Int,
      elapsedMs: Long,
    ) {}
  }
)

জাভা

exoPlayer.addAnalyticsListener(
    new AnalyticsListener() {
      @Override
      public void onPlaybackStateChanged(
          EventTime eventTime, @Player.State int state) {}

      @Override
      public void onDroppedVideoFrames(
          EventTime eventTime, int droppedFrames, long elapsedMs) {}
    });

EventTime যা প্রতিটি কলব্যাকে পাস করা হয়েছে তা ইভেন্টটিকে প্লেলিস্টের একটি মিডিয়া আইটেমের সাথে সংযুক্ত করে, সেইসাথে প্লেব্যাক অবস্থান এবং টাইমস্ট্যাম্প মেটাডেটা:

  • realtimeMs : ইভেন্টের দেয়াল ঘড়ির সময়।
  • timeline , windowIndex এবং mediaPeriodId : প্লেলিস্ট এবং প্লেলিস্টের মধ্যে যে আইটেমটি ইভেন্টের অন্তর্গত তা সংজ্ঞায়িত করে। mediaPeriodId ঐচ্ছিক অতিরিক্ত তথ্য রয়েছে, উদাহরণস্বরূপ ইভেন্টটি আইটেমের মধ্যে একটি বিজ্ঞাপনের অন্তর্গত কিনা তা নির্দেশ করে৷
  • eventPlaybackPositionMs : ইভেন্টটি হওয়ার সময় আইটেমের প্লেব্যাক অবস্থান।
  • currentTimeline , currentWindowIndex , currentMediaPeriodId এবং currentPlaybackPositionMs : উপরের মত কিন্তু বর্তমানে বাজানো আইটেমের জন্য। বর্তমানে বাজানো আইটেমটি ইভেন্টটি যে আইটেমটির সাথে সম্পর্কিত তা থেকে ভিন্ন হতে পারে, উদাহরণস্বরূপ যদি ইভেন্টটি পরবর্তী আইটেমটির প্রাক-বাফারিংয়ের সাথে মিলে যায়।

PlaybackStatsListener এর সাথে ইভেন্ট প্রসেসিং

PlaybackStatsListener হল একটি AnalyticsListener যেটি অন-ডিভাইস ইভেন্ট প্রসেসিং প্রয়োগ করে। এটি PlaybackStats গণনা করে, কাউন্টার এবং প্রাপ্ত মেট্রিক্স সহ:

  • সারাংশ মেট্রিক্স, উদাহরণস্বরূপ মোট প্লেব্যাক সময়।
  • অভিযোজিত প্লেব্যাক মানের মেট্রিক্স, উদাহরণস্বরূপ গড় ভিডিও রেজোলিউশন।
  • রেন্ডারিং কোয়ালিটি মেট্রিক্স, উদাহরণস্বরূপ ড্রপ করা ফ্রেমের হার।
  • রিসোর্স ব্যবহারের মেট্রিক্স, উদাহরণস্বরূপ নেটওয়ার্কে পড়া বাইটের সংখ্যা।

আপনি PlaybackStats Javadoc- এ উপলব্ধ গণনা এবং প্রাপ্ত মেট্রিক্সের একটি সম্পূর্ণ তালিকা পাবেন।

PlaybackStatsListener প্লেলিস্টের প্রতিটি মিডিয়া আইটেমের জন্য আলাদা PlaybackStats গণনা করে, এবং এই আইটেমগুলির মধ্যে ঢোকানো প্রতিটি ক্লায়েন্ট-সাইড বিজ্ঞাপনও। আপনি সমাপ্ত প্লেব্যাক সম্পর্কে অবহিত হওয়ার জন্য PlaybackStatsListener কে একটি কলব্যাক প্রদান করতে পারেন এবং কোন প্লেব্যাক শেষ হয়েছে তা সনাক্ত করতে কলব্যাকে পাস করা EventTime ব্যবহার করুন৷ একাধিক প্লেব্যাকের জন্য বিশ্লেষণ ডেটা একত্রিত করা সম্ভব। PlaybackStatsListener.getPlaybackStats() ব্যবহার করে যে কোনো সময় বর্তমান প্লেব্যাক সেশনের জন্য PlaybackStats জিজ্ঞাসা করাও সম্ভব।

কোটলিন

exoPlayer.addAnalyticsListener(
  PlaybackStatsListener(/* keepHistory= */ true) {
    eventTime: EventTime?,
    playbackStats: PlaybackStats?,
    -> // Analytics data for the session started at `eventTime` is ready.
  }
)

জাভা

exoPlayer.addAnalyticsListener(
    new PlaybackStatsListener(
        /* keepHistory= */ true,
        (eventTime, playbackStats) -> {
          // Analytics data for the session started at `eventTime` is ready.
        }));

PlaybackStatsListener এর কনস্ট্রাক্টর প্রক্রিয়াকৃত ইভেন্টের সম্পূর্ণ ইতিহাস রাখার বিকল্প দেয়। মনে রাখবেন যে এটি প্লেব্যাকের দৈর্ঘ্য এবং ইভেন্টের সংখ্যার উপর নির্ভর করে একটি অজানা মেমরি ওভারহেড হতে পারে। তাই আপনার শুধুমাত্র চূড়ান্ত বিশ্লেষণ ডেটার পরিবর্তে প্রক্রিয়াকৃত ইভেন্টগুলির সম্পূর্ণ ইতিহাসে অ্যাক্সেসের প্রয়োজন হলেই এটি চালু করা উচিত।

মনে রাখবেন যে PlaybackStats শুধুমাত্র মিডিয়ার অবস্থাই নয়, ব্যবহারকারীর খেলার অভিপ্রায় এবং প্লেব্যাক কেন বাধাগ্রস্ত হয়েছে বা শেষ হয়েছে তার মতো আরও বিস্তারিত তথ্য নির্দেশ করতে স্টেটের একটি বর্ধিত সেট ব্যবহার করে:

প্লেব্যাক অবস্থা খেলার জন্য ব্যবহারকারীর উদ্দেশ্য খেলার কোনো ইচ্ছা নেই
প্লেব্যাকের আগে JOINING_FOREGROUND NOT_STARTED , JOINING_BACKGROUND
সক্রিয় প্লেব্যাক PLAYING
ব্যাহত প্লেব্যাক BUFFERING , SEEKING PAUSED , PAUSED_BUFFERING , SUPPRESSED , SUPPRESSED_BUFFERING , INTERRUPTED_BY_AD
শেষ রাজ্য ENDED , STOPPED , FAILED , ABANDONED

প্লেব্যাকের জন্য ব্যবহারকারীর অভিপ্রায়টি সেই সময়গুলিকে আলাদা করার জন্য গুরুত্বপূর্ণ যখন ব্যবহারকারী সক্রিয়ভাবে প্লেব্যাকের জন্য নিষ্ক্রিয় অপেক্ষার সময়গুলি চালিয়ে যাওয়ার জন্য অপেক্ষা করছিলেন৷ উদাহরণস্বরূপ, PlaybackStats.getTotalWaitTimeMs JOINING_FOREGROUND , BUFFERING এবং SEEKING স্টেটে কাটানো মোট সময় ফেরত দেয়, কিন্তু প্লেব্যাক থামানোর সময় নয়৷ একইভাবে, PlaybackStats.getTotalPlayAndWaitTimeMs একটি ব্যবহারকারীর খেলার অভিপ্রায় সহ মোট সময় ফেরত দেবে, এটি হল মোট সক্রিয় অপেক্ষার সময় এবং PLAYING অবস্থায় ব্যয় করা মোট সময়।

প্রক্রিয়া এবং ব্যাখ্যা ঘটনা

আপনি keepHistory=true এর সাথে PlaybackStatsListener ব্যবহার করে প্রক্রিয়াকৃত এবং ব্যাখ্যা করা ঘটনা রেকর্ড করতে পারেন। ফলস্বরূপ PlaybackStats নিম্নলিখিত ইভেন্ট তালিকা থাকবে:

  • playbackStateHistory : EventTime সাথে বর্ধিত প্লেব্যাক স্টেটের একটি অর্ডার করা তালিকা যেখানে তারা আবেদন করতে শুরু করেছে। প্রদত্ত প্রাচীর ঘড়ির সময়ে অবস্থা দেখতে আপনি PlaybackStats.getPlaybackStateAtTime ব্যবহার করতে পারেন।
  • mediaTimeHistory : দেয়াল ঘড়ির সময় এবং মিডিয়া সময় জোড়ার একটি ইতিহাস যা আপনাকে মিডিয়ার কোন অংশগুলি কোন সময়ে চালানো হয়েছিল তা পুনর্গঠন করতে দেয়। প্রদত্ত দেয়াল ঘড়ির সময়ে প্লেব্যাকের অবস্থান দেখতে আপনি PlaybackStats.getMediaTimeMsAtRealtimeMs ব্যবহার করতে পারেন।
  • videoFormatHistory এবং audioFormatHistory : EventTime সাথে প্লেব্যাকের সময় ব্যবহৃত ভিডিও এবং অডিও ফরম্যাটগুলির অর্ডার করা তালিকা যেখানে তারা ব্যবহার করা শুরু হয়েছিল৷
  • fatalErrorHistory এবং nonFatalErrorHistory : যে EventTime সেগুলি ঘটেছে তার সাথে মারাত্মক এবং অ-মারাত্মক ত্রুটির তালিকা করা হয়েছে৷ মারাত্মক ত্রুটিগুলি হল সেইগুলি যেগুলি প্লেব্যাক শেষ করেছে, যেখানে অ-মারাত্মক ত্রুটিগুলি পুনরুদ্ধারযোগ্য হতে পারে৷

একক-প্লেব্যাক বিশ্লেষণ ডেটা

আপনি যদি PlaybackStatsListener ব্যবহার করেন, এমনকি keepHistory=false দিয়েও এই ডেটা স্বয়ংক্রিয়ভাবে সংগ্রহ করা হয়। চূড়ান্ত মান হল সর্বজনীন ক্ষেত্র যা আপনি PlaybackStats Javadoc- এ খুঁজে পেতে পারেন এবং getPlaybackStateDurationMs দ্বারা প্রত্যাবর্তিত প্লেব্যাক স্টেট সময়কাল। সুবিধার জন্য, আপনি getTotalPlayTimeMs এবং getTotalWaitTimeMs এর মতো পদ্ধতিগুলিও খুঁজে পাবেন যা নির্দিষ্ট প্লেব্যাক স্টেট সংমিশ্রণের সময়কাল ফিরিয়ে দেয়।

কোটলিন

Log.d(
  "DEBUG",
  "Playback summary: " +
    "play time = " +
    playbackStats.totalPlayTimeMs +
    ", rebuffers = " +
    playbackStats.totalRebufferCount
)

জাভা

Log.d(
    "DEBUG",
    "Playback summary: "
        + "play time = "
        + playbackStats.getTotalPlayTimeMs()
        + ", rebuffers = "
        + playbackStats.totalRebufferCount);

একাধিক প্লেব্যাকের সমষ্টিগত বিশ্লেষণ ডেটা

আপনি PlaybackStats.merge কল করে একাধিক PlaybackStats একত্রিত করতে পারেন। ফলস্বরূপ PlaybackStats সমস্ত মার্জ করা প্লেব্যাকের সমষ্টিগত ডেটা থাকবে। মনে রাখবেন যে এটিতে পৃথক প্লেব্যাক ইভেন্টের ইতিহাস থাকবে না, কারণ এগুলি একত্রিত করা যাবে না।

PlaybackStatsListener.getCombinedPlaybackStats একটি PlaybackStatsListener এর জীবদ্দশায় সংগৃহীত সমস্ত বিশ্লেষণ ডেটার একটি সমষ্টিগত দৃশ্য পেতে ব্যবহার করা যেতে পারে।

গণনাকৃত সারাংশ মেট্রিক্স

মৌলিক বিশ্লেষণ ডেটা ছাড়াও, PlaybackStats সারাংশ মেট্রিক্স গণনা করার জন্য অনেক পদ্ধতি প্রদান করে।

কোটলিন

Log.d(
  "DEBUG",
  "Additional calculated summary metrics: " +
    "average video bitrate = " +
    playbackStats.meanVideoFormatBitrate +
    ", mean time between rebuffers = " +
    playbackStats.meanTimeBetweenRebuffers
)

জাভা

Log.d(
    "DEBUG",
    "Additional calculated summary metrics: "
        + "average video bitrate = "
        + playbackStats.getMeanVideoFormatBitrate()
        + ", mean time between rebuffers = "
        + playbackStats.getMeanTimeBetweenRebuffers());

উন্নত বিষয়

প্লেব্যাক মেটাডেটার সাথে বিশ্লেষণ ডেটা সংযুক্ত করা

পৃথক প্লেব্যাকের জন্য বিশ্লেষণ ডেটা সংগ্রহ করার সময়, আপনি প্লেব্যাক বিশ্লেষণ ডেটাকে মেটাডেটার সাথে সংযুক্ত করতে চাইতে পারেন যে মিডিয়াটি চালানো হচ্ছে।

MediaItem.Builder.setTag এর সাথে মিডিয়া-নির্দিষ্ট মেটাডেটা সেট করার পরামর্শ দেওয়া হয়। মিডিয়া ট্যাগ হল EventTime অংশ যা কাঁচা ইভেন্টগুলির জন্য রিপোর্ট করা হয় এবং যখন PlaybackStats শেষ হয়, তাই সংশ্লিষ্ট বিশ্লেষণ ডেটা পরিচালনা করার সময় এটি সহজেই পুনরুদ্ধার করা যেতে পারে:

কোটলিন

PlaybackStatsListener(/* keepHistory= */ false) {
  eventTime: EventTime,
  playbackStats: PlaybackStats ->
  val mediaTag =
    eventTime.timeline
      .getWindow(eventTime.windowIndex, Timeline.Window())
      .mediaItem
      .localConfiguration
      ?.tag
    // Report playbackStats with mediaTag metadata.
}

জাভা

new PlaybackStatsListener(
    /* keepHistory= */ false,
    (eventTime, playbackStats) -> {
      Object mediaTag =
          eventTime.timeline.getWindow(eventTime.windowIndex, new Timeline.Window())
              .mediaItem
              .localConfiguration
              .tag;
      // Report playbackStats with mediaTag metadata.
    });

কাস্টম বিশ্লেষণ ঘটনা রিপোর্টিং

আপনার যদি বিশ্লেষণ ডেটাতে কাস্টম ইভেন্টগুলি যোগ করার প্রয়োজন হয় তবে আপনাকে এই ইভেন্টগুলিকে আপনার নিজস্ব ডেটা কাঠামোতে সংরক্ষণ করতে হবে এবং পরে রিপোর্ট করা PlaybackStats সাথে তাদের একত্রিত করতে হবে। যদি এটি সাহায্য করে, আপনি আপনার কাস্টম ইভেন্টগুলির জন্য EventTime দৃষ্টান্ত তৈরি করতে সক্ষম হওয়ার জন্য DefaultAnalyticsCollector প্রসারিত করতে পারেন এবং নিম্নলিখিত উদাহরণে দেখানো হিসাবে ইতিমধ্যে নিবন্ধিত শ্রোতাদের কাছে পাঠাতে পারেন।

কোটলিন

private interface ExtendedListener : AnalyticsListener {
  fun onCustomEvent(eventTime: EventTime)
}

private class ExtendedCollector : DefaultAnalyticsCollector(Clock.DEFAULT) {
  fun customEvent() {
    val eventTime = generateCurrentPlayerMediaPeriodEventTime()
    sendEvent(eventTime, CUSTOM_EVENT_ID) { listener: AnalyticsListener ->
      if (listener is ExtendedListener) {
        listener.onCustomEvent(eventTime)
      }
    }
  }
}

// Usage - Setup and listener registration.
val player = ExoPlayer.Builder(context).setAnalyticsCollector(ExtendedCollector()).build()
player.addAnalyticsListener(
  object : ExtendedListener {
    override fun onCustomEvent(eventTime: EventTime?) {
      // Save custom event for analytics data.
    }
  }
)
// Usage - Triggering the custom event.
(player.analyticsCollector as ExtendedCollector).customEvent()

জাভা

private interface ExtendedListener extends AnalyticsListener {
  void onCustomEvent(EventTime eventTime);
}

private static class ExtendedCollector extends DefaultAnalyticsCollector {
  public ExtendedCollector() {
    super(Clock.DEFAULT);
  }

  public void customEvent() {
    AnalyticsListener.EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
    sendEvent(
        eventTime,
        CUSTOM_EVENT_ID,
        listener -> {
          if (listener instanceof ExtendedListener) {
            ((ExtendedListener) listener).onCustomEvent(eventTime);
          }
        });
  }
}

// Usage - Setup and listener registration.
ExoPlayer player =
    new ExoPlayer.Builder(context).setAnalyticsCollector(new ExtendedCollector()).build();
player.addAnalyticsListener(
    (ExtendedListener) eventTime -> {
      // Save custom event for analytics data.
    });
// Usage - Triggering the custom event.
((ExtendedCollector) player.getAnalyticsCollector()).customEvent();