کار با MediaPlayer و مدیریت حقوق دیجیتال (DRM)

با شروع از اندروید ۸.۰ (سطح API ۲۶)، MediaPlayer شامل APIهایی است که از پخش محتوای محافظت‌شده با DRM پشتیبانی می‌کنند. APIهای DRM مدیاپلیر مشابه API سطح پایین ارائه شده توسط MediaDrm هستند، اما در سطح بالاتری عمل می‌کنند و اشیاء استخراج‌کننده، DRM و رمزنگاری زیرین را در معرض نمایش قرار نمی‌دهند.

اگرچه رابط برنامه‌نویسی نرم‌افزاری MediaPlayer DRM تمام قابلیت‌های MediaDrm را ارائه نمی‌دهد، اما از رایج‌ترین موارد استفاده پشتیبانی می‌کند. پیاده‌سازی فعلی می‌تواند انواع محتوای زیر را مدیریت کند:

  • فایل‌های رسانه محلی محافظت‌شده توسط Widevine
  • فایل‌های رسانه‌ای از راه دور یا در حال پخش که توسط Widevine محافظت می‌شوند

قطعه کد زیر نحوه استفاده از متدهای جدید DRM MediaPlayer را در یک پیاده‌سازی همزمان نشان می‌دهد.

برای مدیریت رسانه‌های تحت کنترل DRM، باید متدهای جدید را در کنار جریان معمول فراخوانی‌های MediaPlayer، همانطور که در این مثال نشان داده شده است، بگنجانید:

کاتلین

mediaPlayer?.apply {
    setDataSource()
    setOnDrmConfigHelper() // optional, for custom configuration
    prepare()
    drmInfo?.also {
        prepareDrm()
        getKeyRequest()
        provideKeyResponse()
    }

    // MediaPlayer is now ready to use
    start()
    // ...play/pause/resume...
    stop()
    releaseDrm()
}

جاوا

setDataSource();
setOnDrmConfigHelper(); // optional, for custom configuration
prepare();
if (getDrmInfo() != null) {
  prepareDrm();
  getKeyRequest();
  provideKeyResponse();
}

// MediaPlayer is now ready to use
start();
// ...play/pause/resume...
stop();
releaseDrm();

طبق معمول، با مقداردهی اولیه شیء MediaPlayer و تنظیم منبع آن با استفاده از setDataSource() شروع کنید. سپس، برای استفاده از DRM، این مراحل را انجام دهید:

  1. اگر می‌خواهید برنامه شما پیکربندی سفارشی انجام دهد، یک رابط OnDrmConfigHelper تعریف کنید و آن را با استفاده از setOnDrmConfigHelper() به پخش‌کننده متصل کنید.
  2. تابع prepare() را فراخوانی کنید.
  3. تابع getDrmInfo() را فراخوانی کنید. اگر منبع دارای محتوای DRM باشد، این متد یک مقدار غیر تهی MediaPlayer.DrmInfo برمی‌گرداند.

اگر MediaPlayer.DrmInfo وجود دارد:

  1. نقشه UUID های موجود را بررسی کنید و یکی را انتخاب کنید.
  2. با فراخوانی تابع prepareDrm() پیکربندی DRM را برای منبع فعلی آماده کنید.
    • اگر یک فراخوانی OnDrmConfigHelper ایجاد و ثبت کرده‌اید، هنگام اجرای prepareDrm() فراخوانی می‌شود. این به شما امکان می‌دهد قبل از باز کردن جلسه DRM، پیکربندی سفارشی ویژگی‌های DRM را انجام دهید. فراخوانی به صورت همزمان در رشته‌ای که prepareDrm() را فراخوانی کرده است، فراخوانی می‌شود. برای دسترسی به ویژگی‌های DRM، getDrmPropertyString() و setDrmPropertyString() را فراخوانی کنید. از انجام عملیات طولانی خودداری کنید.
    • اگر دستگاه هنوز آماده‌سازی نشده باشد، prepareDrm() به سرور آماده‌سازی نیز برای آماده‌سازی دستگاه دسترسی پیدا می‌کند. این کار بسته به اتصال شبکه می‌تواند مدت زمان متغیری طول بکشد.
  3. برای دریافت آرایه‌ای از بایت‌های درخواست کلید غیرشفاف جهت ارسال به سرور لایسنس، تابع getKeyRequest() را فراخوانی کنید.
  4. To inform the DRM engine about the key response received from the license server, call provideKeyResponse() . The result depends on the type of key request:
    • اگر پاسخ مربوط به درخواست کلید آفلاین باشد، نتیجه یک شناسه مجموعه کلید خواهد بود. می‌توانید از این شناسه مجموعه کلید به همراه تابع restoreKeys() برای بازیابی کلیدها در یک جلسه جدید استفاده کنید.
    • اگر پاسخ مربوط به درخواست پخش یا انتشار باشد، نتیجه null است.

آماده‌سازی DRM به صورت غیرهمزمان

به طور پیش‌فرض، prepareDrm() به صورت همزمان اجرا می‌شود و تا زمان اتمام آماده‌سازی، مسدود می‌شود. با این حال، اولین آماده‌سازی DRM در یک دستگاه جدید نیز ممکن است نیاز به آماده‌سازی داشته باشد که prepareDrm() به صورت داخلی آن را مدیریت می‌کند و ممکن است به دلیل عملیات شبکه، تکمیل آن مدتی طول بکشد. شما می‌توانید با تعریف و تنظیم یک MediaPlayer.OnDrmPreparedListener از مسدود شدن در prepareDrm() جلوگیری کنید.

Set an OnDrmPreparedListener . prepareDrm() performs the provisioning (if needed) and preparation in the background. When provisioning and preparation finish, the system calls the listener. Don't make any assumptions about the calling sequence or the thread in which the listener runs (unless you register the listener with a handler thread). The system can call the listener before or after prepareDrm() returns.

DRM را به صورت ناهمزمان تنظیم کنید

شما می‌توانید DRM را به صورت غیرهمزمان با ایجاد و ثبت MediaPlayer.OnDrmInfoListener برای آماده‌سازی DRM و MediaPlayer.OnDrmPreparedListener برای شروع پخش، مقداردهی اولیه کنید. آن‌ها در رابطه با prepareAsync() کار می‌کنند، همانطور که در این مثال نشان داده شده است:

کاتلین

setOnPreparedListener()
setOnDrmInfoListener()
setDataSource()
prepareAsync()
// ...

// If the data source content is protected you receive a call to the onDrmInfo() callback.
override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) {
    mediaPlayer.apply {
        prepareDrm()
        getKeyRequest()
        provideKeyResponse()
    }
}

// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
override fun onPrepared(mediaPlayer: MediaPlayer) {
    mediaPlayer.start()
}

جاوا

setOnPreparedListener();
setOnDrmInfoListener();
setDataSource();
prepareAsync();
// ...

// If the data source content is protected you receive a call to the onDrmInfo() callback.
onDrmInfo() {
  prepareDrm();
  getKeyRequest();
  provideKeyResponse();
}

// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
onPrepared() {

start();
}

مدیریت رسانه‌های رمزگذاری شده

با شروع از اندروید ۸.۰ (سطح API ۲۶)، MediaPlayer همچنین می‌تواند رسانه‌های رمزگذاری شده با طرح رمزگذاری مشترک (CENC) و سطح نمونه HLS (METHOD=SAMPLE-AES) را برای انواع جریان ابتدایی H.264 و AAC رمزگشایی کند. رسانه‌های رمزگذاری شده با قطعه کامل (METHOD=AES-128) قبلاً پشتیبانی می‌شدند.

بیشتر بدانید

Jetpack Media3 راهکار پیشنهادی برای پخش رسانه در برنامه شماست. درباره آن بیشتر بخوانید .

این صفحات موضوعات مربوط به ضبط، ذخیره و پخش صدا و تصویر را پوشش می‌دهند: