Android SDK ও নেটিভ Media3
টেনে সাজানো যায় এমন প্লেলিস্ট, সংরক্ষিত শাফল ও রিপিট সেটিং এবং অফলাইনে আগের অবস্থান থেকে প্লেব্যাক চালুর সুবিধাসহ Android প্লেয়ার ডাউনলোড করুন। DRM-X বা নেটিভ Media3 দিয়ে সুরক্ষিত প্লেব্যাক সংযুক্ত করুন।
UI কাস্টমাইজেশন, প্যারামিটারের ডিফল্ট মান এবং জীবনচক্রের উদাহরণের জন্য PLAYER-UI-CONFIGURATION.md পড়ুন। প্লেয়ারের নিজস্ব পপআপ প্যানেল অস্বচ্ছ; সাবটাইটেল ও ওয়াটারমার্কের অস্বচ্ছতা আলাদাভাবে নির্ধারণ করা হয়।
SDK ZIP-এর DEMO-QUICKSTART.md অনুসরণ করে PHP ডেমো চেষ্টা করুন। নিজের কনটেন্ট ব্যবহার করতে প্রথমে ওয়েবসাইট ও ব্যাকএন্ড ইন্টিগ্রেশন সম্পন্ন করুন, তারপর MOBILE-AND-TV-APPS.md অনুসরণ করে অ্যাপটিকে একই লগইন ব্যবস্থা ও দেখার অনুমতির নিয়মের সঙ্গে যুক্ত করুন।
চেষ্টা করো Android প্লেয়ার#
ডাউনলোড করা হয়েছে Android নমুনা APK
1.0.0-beta.11 · 12.15 MB · Android 6.0+ (API 23+) · DRM-X 6.0 Player
- এই ওয়েবপেজটি আপনার পাতায় খুলুন Android ফোন এবং ডাউনলোড করুন APK.
- ডাউনলোড উইন্ডো খুলুন। Android জিজ্ঞাসা, ফাইল ব্রাউজার অথবা ফাইল ম্যানেজার থেকে ইনস্টলেশন অনুমোদন করা হবে ইনস্টল করুন.
- খুলুন DRM-X 6.0 প্লেয়ার- তুমি এখানে থাকো, আর ভিডিওটা খুলে দাও চালান বাটন । মিডিয়া চালানোর সময় এই অ্যাপ্লিকেশনটি একটি স্ট্রিমিং লাইসেন্সের অনুরোধ জানায় ।
- খুলুন অবাঞ্ছিত বস্তু সংক্রান্ত বৈশিষ্ট্য গুণমান, অডিও, দিশা ও আবর্তন ব্যবস্থার অনুরূপ মাপের উপর্যমান নির্বাচন করুন।
- ভিডিওর তিন-রেখার মেনু খুলে Download বেছে নিন। Offline Mode-এর জন্য Downloaded videos চালু করুন; Online Mode-এর জন্য বন্ধ করুন। Offline Mode-এ ওই ভিডিওর মেনু থেকে Delete বেছে নিয়ে নিশ্চিত করুন। লাইসেন্স নবায়নে সংযোগ ও বর্তমান বৈধ অনুমতি প্রয়োজন; অফলাইন ত্রুটি হলে অফলাইনেই থাকা বা অনলাইনে যাওয়া বেছে নিতে পারেন।
ডিস্কের মধ্যে ডাউনলোডের কাজ বর্তমানে চলছে। Android লাইসেন্স প্রস্তুত করার সময় অ্যাপ্লিকেশনটি বন্ধ অথবা ট্র্যাক বন্ধ করা হবে। অবশিষ্ট বস্তু প্রস্তুত করার সময় এটি নতুন করে খোলা যাবে। অফ-লাইন অবস্থায় থাকা সামগ্রীর জন্য অফ-লাইন অবস্থায় এই কাজ করছে; শুধুমাত্র ক্যাশে করা মিডিয়া ব্যবহার করা হবে অথবা তালিকার মধ্যে কর্ম সমাপ্ত করার জন্য প্রয়োজনীয় অতিরিক্ত সামগ্রী লোড করা আবশ্যক।
নমুনা APK জনসম্মুখে এবং মূল্যায়নের জন্য স্বাক্ষর করা হয়েছে। AAR এবং পূর্ণ SDK নীচে যোগ্য কনসোল অ্যাকাউন্টগুলি উপলব্ধ রয়েছে । আপনার নিজের প্রোডাকশনের জন্য স্বাক্ষর স্বাক্ষর করুন এবং এই ডেমো থেকে লগ- ইন করুন ।
APK চেকসাম এবং USB ইনস্টলেশন
SHA-256:
b96ba527ddf9abae5bff2f8b85a39a12b59c934aaacde1961c8096aa32524c54সহ Android প্ল্যাটফর্ম-tools এবং অনুমোদিত USB ডিভাইস:
adb install -r drmx-android-player-1.0.0-beta.11.apkএই ইনস্টল করুন APK বিদ্যমান অফিসিয়াল নমুনা ছাড়া, এটি আন-ইনস্টল করা হয়নি। একই স্বাক্ষর এবং অ্যাপ্লিকেশনও স্বাক্ষর করা হয়েছে। ID ডাউনলোড, অফলাইন লাইসেন্স সংরক্ষণ করুন, সংরক্ষিত অবস্থান ও বৈশিষ্ট্য সংরক্ষণ করুন। অন্য কোনো স্বাক্ষরকারী কি ব্যবহার করে একটি পৃথক অ্যাপ্লিকেশন ব্যবহার করুন। ID এ্যাপস এবং নমুনার অফলাইন লাইসেন্স সংরক্ষণ করে রাখতে হবে।
Download controls and language names in preview.40#
Connect to the internet before starting a download. Choose the permitted video quality and audio track in the download dialog; available subtitles are included. Audio and subtitle menus display each language in its own language, such as English and 中文. Customer configuration and device DRM support determine the available quality ceiling.
Offline Mode-এ ভিডিওর তিন-রেখার মেনু খুলে Delete বেছে নিন। নিশ্চিত করলে শুধু ওই ভিডিওর স্থানীয় এনক্রিপ্ট করা মিডিয়া ও লাইসেন্সের রেফারেন্স মুছে যাবে; Cancel এগুলো রেখে দেয়। আবার ডাউনলোড করতে পুনরায় সংযুক্ত হন।
New downloads require an internet connection. A queued transfer can pause when connectivity disappears and resume after reconnection. Completed downloads play offline while their device-bound licenses remain valid. Playlist posters and seek-preview thumbnails remain cached as described below.
Offline artwork and downloads in preview.39#
Playlist posters and seek-preview thumbnails are saved on the device with their artwork metadata. They remain available after closing and reopening the app without a network connection. After upgrading, open the offline demonstration library once while connected and allow the images to load; existing encrypted videos do not need to be downloaded again.
Wait for each video to finish downloading, then switch off both Wi-Fi and mobile data and choose Play offline. Test the downloaded playlist, selected audio and included captions. Reconnect before using Renew when a stored license needs renewal. Install this update over the existing sample to retain its downloads and settings.
Publisher images must be available while connected before they can appear offline. Images use a bounded 96 MiB app-private store, separate from encrypted media and licenses; older artwork can be evicted when this store fills. Missing images do not bypass DRM or prevent an otherwise valid downloaded video from playing.
Live DRM in preview.13#
17 সেপ্টেম্বর 2026 প্রকাশিত হয়েছে। ফোন অ্যাপ এবং গ্রাহক SDK 4K লাইভ DRM পরীক্ষা অন্তর্ভুক্ত করে। লাইভ প্লেব্যাক তাজা ম্যানিফেস্ট ব্যবহার করে এবং ডাউনলোড করা যাবে না। পরীক্ষা ইভেন্ট শুধুমাত্র একটি সক্রিয় সম্প্রচারের সময় উপলব্ধ. আপনার নিজস্ব ইভেন্ট তৈরি করতে AWS এবং OBS সেটআপ গাইড অনুসরণ করুন৷
নতুন কি আছে Android প্লেয়ার প্রাকদর্শন ১২.১২#
১৪ সেপ্টেম্বর, ২০১২ তারিখে মুক্তি প্রাপ্ত Widevine লাইসেন্সের মেয়াদ উত্তীর্ণ হয়েছে অথবা এক মিনিটের মধ্যে একটিও অবশিষ্ট রয়েছে। এটি হতে পারে আরও বেশি। Media3 ত্রুটি 6004এবং একটি HTTP সংযুক্ত হওয়ার সময় ত্রুটি অথবা সংযোগ স্থাপন করা হয়েছে DNS সংযোগ বিচ্ছিন্ন
এটা প্লেয়ার বর্তমানে ডাউনলোড করা লাইসেন্সটি পুনঃস্থাপিত হয়েছে। বৈধ লাইসেন্স দ্বারা সেগুলির স্থায়ীরূপে সংরক্ষণ করা হয়; মেয়াদ পূর্ণ হওয়ার পরে লাইসেন্সের সংখ্যা সংরক্ষিত হবে। সংযোগ এবং ট্যাপ করুনলাইসেন্স বৈধতা এবং নিরাপত্তা নিয়মাবলী ডিভাইসের মধ্যে অনুমোদিত । ডায়াগনস্টিকও অন্তর্ভুক্ত । HTTP কোনো নেটওয়ার্ক কাজ ব্যর্থ হলে, কোনো অনুরোধের উত্তর না করে অথবা লাইসেন্স প্রাপ্ত হলে অবস্থা প্রদর্শন করা হবে।
- বিদ্যমান অফিসিয়াল অ্যাপ্লিকেশনের প্রাকদর্শন ইনস্টল করুন । আপনার বর্তমান অ্যাপটি তথ্য এবং ডাউনলোড করুন ।
- যদি পাথ ইঙ্কার বা অন্য কোন ডাউনলোড ভিডিও পুন:নির্মাণের প্রয়োজন হয়, তাহলে ইন্টারনেটে সংযোগ করুন, যে ভিডিও এবং কল করুন নতুন করে প্রদর্শন.
- অপেক্ষা করো নতুন করে সাজানো হয়েছে। অফলাইন মোডে খেলতে প্রস্তুত।তারপর সে জড়ো করল এবং ঘোষণা করলো , অফলাইন মোডে আরম্ভ করা হবেএনক্রিপ্ট করা ভিডিও ডাউনলোড করা হয়েছে।
This release retains preview.11's controls and playlist features. The public evaluation app and its embedded player identify preview.12; at that release, the separately distributed Console SDK was preview.10 / bundle 20260910.8.
নতুন কি আছে Android প্লেয়ার ১১.১১#
১৪ সেপ্টেম্বর, ২০১২ তারিখে মুক্তি লাভ। এই মূল্যায়নের মধ্যে রয়েছে সর্বশেষ পরীক্ষা। প্লেয়ার কন্ট্রোল এবং প্লেব্যাক উন্নত Android এবং আপেল প্লেয়ার.
- ভিডিওতে নিয়ন্ত্রণ: মাল্টি-ভিডিও প্লে-লিস্টের জন্য Comples চালানো/Pult; CCবৈশিষ্ট্য ও একটি পূর্ণপর্দা বাটন । ২ সেকেন্ড পর আড়াল করার পর নিয়ন্ত্রণ করা হয়; ভিডিওটা আবার প্রকাশ করার জন্য ।
- শিরোনাম ও প্লে-ব্যাক সংক্রান্ত বৈশিষ্ট্য ব্যবহৃত CC উপলব্ধ অনুবাদলিপির বৈশিষ্ট্য প্রদর্শন অথবা আড়াল করা হবে। ডাউনলোড করার জন্য অডিও, অডিও, গতি ও সীমাহীন মান নির্বাচন করুন। বর্তমানে ডাউনলোড করা সকল ট্র্যাকগুলি ডাউনলোড করা হবে।
- টেনে নিয়ে যাও: (g) প্লে-লিস্টের অবস্থান পরিবর্তনের জন্য একটি প্লে-লিস্ট ব্যবস্থাপনার ব্যবস্থা। সংরক্ষিত এই ব্যবস্থা দ্বারা একটি অ্যাপ্লিকেশন পুনরায় আরম্ভ করা হয় ও ডাউনলোড প্লে-লিস্ট থেকে এটি পুনরুদ্ধার করা হয়। বর্তমান ভিডিও প্লে-লিস্টের মধ্যে উপস্থিত রয়েছে। এগিয়ে যাওয়ার জন্য উইন্ডোর উপর ক্লিক করুন।
- সংরক্ষিত স্ট্যাচার এবং পুনরাবৃত্তি: নির্বাচিত মোডগুলি অনলাইন ও অফলাইন মোডে আরম্ভ করা হবে। প্লে-লিস্টের শেষ করার পরে "পরবর্তী" মেনু থেকে "পরবর্তী" প্রতিক্রিয়া মুছে ফেলা হবে।
- পুনরায় আরম্ভ করা হবে: প্রতিটি ভিডিওর সংরক্ষিত VOD ডাউনলোড করা অথবা ডাউনলোড করা অবস্থায় এই অবস্থান পুনরায় আরম্ভ করা হচ্ছে। বর্তমানে এই ডিভাইসের মধ্যে উপস্থিত সকল উপস্থিত ডিস্কের সাথে সুসংগত নয়।
প্লেলিস্ট সাজান, ক্রম সংরক্ষণ করুন এবং আবার প্লেব্যাক শুরু করুন। অফলাইনে দেখতে সম্পূর্ণ ডাউনলোড ও ব্যবহারযোগ্য, মেয়াদোত্তীর্ণ নয় এমন অফলাইন লাইসেন্স প্রয়োজন।
The preview.11 release updated the public evaluation APK. The current Console SDK is 1.0.0-beta.14, bundle 20261028.1; the integration instructions below use that bundle.
১.৪ একটি সমন্বিত পাথ বেছে নিন#
Use DrmXPlayer, the phone sample and the offline manager. Keep your own login and business rules.
PATH বি. KEEP YOUR UIMedia3 + DRM-X সহায়ক তথ্যউপস্থিত মান পরিবর্তন করুন প্লেয়ার এবং নথিবদ্ধ নথি ডাউনলোড করুন।
PATH সি. NATIVE ONLYMedia3 ছাড়া AARএকই ব্যাক-এন্ড চুক্তি এবং স্থানীয় লাইসেন্স লাইফসাইকেল, না। DRM-X প্লেয়ার নির্ভরতা।
Developer Tools → Device SDKs থেকে ডাউনলোড করুন। SDK ব্যবহারে সক্রিয় Professional বা Enterprise অনুমতি প্রয়োজন; অনুমোদিত Professional মূল্যায়নও অন্তর্ভুক্ত। Standard-এ নিজস্ব প্লেয়ারের জন্য নেটিভ APIs থাকছে। সেশন তৈরি ও লাইসেন্স নবায়নের সময় SDK অনুমতি যাচাই হয়; অফলাইন লাইসেন্সের মেয়াদ অ্যাকাউন্টের সেবা সময়সীমার পরে যায় না।
Current preview: 1.0.0-beta.14 · customer bundle 20261028.1 · Media3 1.11.0. The ZIP contains a local Maven repository, Gradle wrapper, annotated README, phone/TV/native samples, an installable phone sample APK in apks/, and offline integration notes. It contains no customer credentials or protected movies.
২) আপনার বিষয়বস্তু এবং ব্যাক-এন্ড প্রস্তুত করুন#
- প্যাকেজ ও প্রকাশনা Widevine- দ্রুত এনক্রিপ্ট করা হবে DASH আপনার মধ্যে শিরোনাম DRM-X পরিবেশ, তার কপি প্রকাশিত Content ID.
- আপনার সার্ভার কনফিগার করুন Environment ID, Site Key এবং Access Keyব্যবহার করুন । ডাউনলোডযোগ্য ডাউনলোড PHP যোগাযোগ সংক্রান্ত বিবরণ কাজের জন্য.
- ব্যবহারকারীর লগ-ইন ও শিরোনাম ধার্য করা হবে। আপনার অ্যাপ্লিকেশনটির সংক্ষিপ্ত ব্যবহারকারী দ্বারা নিজের ব্যাক-এন্ডে আপনার ব্যাক-এন্ডে উপস্থিত করা অবস্থায় আপনার ব্যাক- এন্ডটিচ করুন; আপনার ব্যাক-এন্ড বিষয়বস্তু, পলিসি ও বিশ্বস্ত URL- টি নির্বাচন করে নিন।
- অনলাইন প্লে-ব্যাকে প্রথমে সঞ্চালন করুন Widevine- ডিভাইস খালি হাতে রাখুন, চুক্তি করার পর থেকে।
এনক্রিপ্ট করা ভিডিও ও DRM লাইসেন্স আলাদা পথে সরবরাহ করা হয়
CDN এনক্রিপ্ট করা ভিডিও সরবরাহ করে। আপনার ব্যাকএন্ড দেখার অধিকার যাচাই করে, আর DRM লাইসেন্স পরিষেবা সামঞ্জস্যপূর্ণ ডিভাইসে ডিক্রিপশনের অনুমতি দেয়।
- স্টোরেজ / CDN
প্লেয়ারে এনক্রিপ্ট করা মিডিয়া সরবরাহ করে।
- আপনার ব্যাকএন্ড
দর্শকের দেখার অনুমতি যাচাই করে এবং DRM-X থেকে প্লেব্যাকের অনুমোদন চায়।
- DRM-X
প্লেব্যাকের অনুমোদন যাচাই করে এবং DRM লাইসেন্সের অনুরোধ প্রক্রিয়া করে।
- প্লেয়ার + ডিভাইস
ডিভাইসের DRM সিস্টেম ব্যবহার করে লাইসেন্স গ্রহণ করে এবং এনক্রিপ্ট করা মিডিয়া চালায়।
| এই মান পরিবর্তন করুন | যেখানে এটা আছে | মানে |
|---|---|---|
| sessionEndpoint | Android | আপনার HTTPS প্লে-ব্যাকের গতি হ্রাস করা হবে, raw লাইসেন্স সার্ভার নয় URL. |
| offlineEndpoint | Androidঅফ-লাইন অবস্থায় রয়েছে | আপনার প্রাপ্ত/নতুন পরিচয় পরিচয় নিশ্চিতকরণ(_v) |
| contentId | Android, সমর্থিত ব্যাক-এন্ড | এনক্রিপশন সংরক্ষিত Content ID প্রদর্শকের অধিকার আছে। |
| গ্রাহক অ্যাক্সেস টোকেন | লগ-ইন করার পরে অনুমোদন করা হবে | তোমার সংক্ষিপ্ত-বিড়াল ব্যবহারকারী টোকেন, কখনো না Site Key অথবা Access Key. |
| Environment ID, Site Key, Access Key | সার্ভারের কনফিগারেশন | DRM-X অ্যাকাউন্টের পরিচয় যাচাইয়ের তথ্য। APK, HTML বা সোর্স কন্ট্রোলে এই তথ্য কখনো অন্তর্ভুক্ত করবেন না। |
| নীতি ও বিশ্বস্ত পরিচয় URL | আপনার ব্যাকএন্ড | ব্যবসা এবং প্যাকেজ ম্যাপিং। অ্যাপ্লিকেশন থেকে এগুলো গ্রহণ করবেন না। |
৩. ইনস্টল করুন এবং চালান SDK#
ZIP ফাইল আনজিপ করে তার মূল ফোল্ডার Android Studio-তে খুলুন। JDK 17, Android SDK 36 ও Android Gradle Plugin 9.2.0 ব্যবহার করুন; সঙ্গে থাকা wrapper-এ Gradle 9.4.1 ব্যবহৃত হয়। ডিভাইসের ন্যূনতম API সংস্করণ 23। বিল্ডের নির্ভরতা ডাউনলোড করতে ইন্টারনেট প্রয়োজন। samples.phone নির্বাচন করে Run চাপুন। প্রাথমিক সেটিংসে পাবলিক ডেমোর ব্যাকএন্ড ও ভিডিও ব্যবহার করা হয়; নিজস্ব ব্যাকএন্ডে যাওয়ার আগে ডেমোর লগইন ও স্ট্রিমিং নিয়ন্ত্রণ ব্যবহার করুন।
# Windows
gradlew.bat :samples:phone:assembleDebug
# macOS / Linux
sh gradlew :samples:phone:assembleDebug
উপস্থিত অ্যাপ্লিকেশনের জন্য একটি প্রতিলিপি নির্মাণ করুন ZIP`%s' maven/ আপনার প্রজেক্টের মধ্যে ফোল্ডারটি নির্মাণ করুন। settings.gradle.kts:
dependencyResolutionManagement {
repositories {
maven { url = uri(rootDir.resolve("maven")) }
google()
mavenCentral()
}
}
অ্যাপ্লিকেশনের মডিউলের মধ্যে build.gradle.kts:
dependencies {
implementation("com.haihaisoft.drmx:drmx-universal-player:1.0.0-beta.14")
}
স্থায়ীরূপে বর্জন করা হচ্ছে AAR এর পরিবর্তে
এটা রেখে দে AAR অ্যাপ্লিকেশনের মডিউলের মধ্যে libs/অবস্থান্তর AAR স্বয়ংক্রিয়রূপে অতিক্রমকৃত নির্ভরতার মীমাংসায় কোনো মিল পাওয়া যায়নি, তাই তিনটি মিল যোগ করুন Media3 স্থায়ীভাবে নিজের উপর নির্ভর করুন। দুটি ফর্ম ইনস্টল করা যাবে না।
implementation(files("libs/drmx-universal-player-1.0.0-beta.14.aar"))
implementation("androidx.media3:media3-exoplayer:1.11.0")
implementation("androidx.media3:media3-exoplayer-dash:1.11.0")
implementation("androidx.media3:media3-ui:1.11.0")এর মধ্যে AndroidManifest.xmlএই সাধারণ নমুনার জন্য ইন্টারনেট ব্যবহারের অনুমতি দিন ও ব্যাক-এন্ড নিষ্ক্রিয় করুন। এই বৈশিষ্ট্যের জন্য কোনো সুনির্দিষ্ট ডিভাইসটি ব্যাক-আপ করা প্রয়োজন।
<uses-permission android:name="android.permission.INTERNET" />
<application android:allowBackup="false" android:usesCleartextTraffic="false" ... >
ফোনের নমুনা অনুসন্ধান করুন MainActivity.kt উল্লিখিত সময় অবধি drmx.sessionEndpoint, drmx.offlineEndpoint, drmx.contentId এবং customer.loginEndpointএই ফল- আপ বৈশিষ্ট্য পরিবর্তন করুন, অথবা আপনার অ্যাপ্লিকেশন থেকে প্রাপ্ত সূচনাবার্তাগুলি সরিয়ে নিন । customer.accessToken শোবার সময়। ZIP README প্রতিটি পরামিতির ব্যাখ্যা করুন।
একটি পরীক্ষা গঠন করুন APK ব্যবহার AAR#
এই উদাহরণটি সম্পূর্ণ থেকে রানিং ফোন প্রকল্প ব্যবহার করে SDK ZIP এবং স্পষ্টভাবে সংযোগ করুন AARএকই ধরনের লোকদের জন্য এটি একটি উপস্থিত রয়েছে । Android অ্যাপ।
- Download and extract the full Android SDK ZIP. Open its root folder in Android Studio.
- Keep
libs/drmx-universal-player-1.0.0-beta.14.aarin the extracted root. Use JDK 17, Android SDK 36 and the included Gradle wrapper. - এর মধ্যে
samples/phone/build.gradle.ktsপ্রতিস্থাপন (_R) DRM-X নিচের এন্ট্রিগুলোর মাধ্যমে মাভেন নির্ভরতাdependencies..এবং অবশিষ্ট ফাইল প্রস্তুত করুন.
implementation(files(rootProject.file("libs/drmx-universal-player-1.0.0-beta.14.aar")))
implementation("androidx.media3:media3-exoplayer:1.11.0")
implementation("androidx.media3:media3-exoplayer-dash:1.11.0")
implementation("androidx.media3:media3-ui:1.11.0")
মুছে ফেলুন implementation("com.haihaisoft.drmx:drmx-universal-player:1.0.0-beta.14") একই রকম SDK একই ফ্ল্যাটে দুবার যোগ করা হয়নি। AAR তিনটা লাগবে। Media3 উপরের নির্ভরতার উপর নির্ভর করে।
- ডাউনলোড ডেমোর পাশাপাশি আপনার নিজের পরীক্ষা বিল্ড, ফোনের মডিউল পরিবর্তন করুন
applicationIdচিহ্নিত স্থানে চলুনcom.example.drmxtestএই সরবরাহকৃত নমুনার জন্য নিজের পরিচয় পত্র অপরিবর্তিত রাখা হয়নি । - বিল্ড APKঅতঃপর আমি একে নিজের দিকে ধীরে ধীরে গুটিয়ে আনি । USB-সংযোগ স্থাপিত Android ডিভাইসের সাথে ব্যবহার করা হবে USB ডিবাগ ব্যবস্থা.
# Windows, from the extracted SDK root
gradlew.bat :samples:phone:assembleDebug
adb install -r samples/phone/build/outputs/apk/debug/phone-debug.apk
# macOS / Linux
sh gradlew :samples:phone:assembleDebug
adb install -r samples/phone/build/outputs/apk/debug/phone-debug.apk
পরীক্ষা করুন এবং ট্যাপ প্লে করুন। প্রারম্ভিক সময়ে প্রদত্ত ফোন সোর্সটি একই ধরনের পাবলিক ডেমো ব্যবহার করে। আপনার নিজের শিরোনাম পরিবর্তন করে, চিহ্নিত সেশন/ডোমার্ডেস পয়েন্ট পরিবর্তন করুন ও প্রকাশ করুন Content ID %s এর মধ্যে MainActivity.ktআপনার নিজের ব্যবহারকারী হাতে কম অনুমোদন দিন। আপনার সার্ভারে আপনার সার্ভার রাখা হয়েছে। Site Key এবং Access Key.
সংক্ষিপ্ত নিয়ন্ত্রণ থেকে আসে DrmXPlayerView এর মধ্যে AARসরবরাহকৃত কাজ প্রদর্শন করছে প্লে-পর্তুগ, পরিবর্তন, ডাউনলোড করুন মালিকানা, অফলাইন প্লেব্যাক এবং পুন:স্থাপন করুন। নিয়ন্ত্রণ সংক্রান্ত একটি উদাহরণ আপনার নিজের অ্যাপ্লিকেশনের তথ্য হিসাবে এই প্রদর্শন করা হলে নীচে কপি করুন।
৪. সার্ভারের অনুরোধ এবং ডিফল্ট পলিসি#
এটা Android অ্যাপটি আপনার ব্যাক- আপ সেশন- এ আপনার ব্যাক- এন্ড জিজ্ঞাসা করে । আপনার ব্যাক- এন্ড ব্যবহারকারীর পরিচয় প্রমাণকরণ, মানচিত্র Content ID মিডিয়া এবং কল প্রকাশ করুন DRM-Xআর- এস ! চালানো হবে API সম্পূর্ণ স্ট্রিমিং চুক্তির জন্য।
{
"contentId": "YOUR-PUBLISHED-CONTENT-ID",
"contentType": "vod",
"drmSystem": "widevine",
"playbackMode": "streaming",
"platformCapabilities": {
"clientPlatform": "android",
"drmSystems": ["widevine"], "manifestTypes": ["dash"],
"maximumHeight": 1080, "secureDecoder": false, "persistentState": false
}
}
উপরের রক্ষণশীল ক্ষমতা দাবি করে না Widevine L1ব্যবহার করুন SDK'শক্তির ক্ষমতা', অথবা আপনার নিজের ডিভাইস মূল্যায়ন করুন। প্রকৃত ডিভাইসের সাথে সামঞ্জস্য বজায় রাখার জন্য ক্লায়েন্ট ক্ষমতা সমর্থন করে; তারা কখনোই মান পূরণ করতে পারবে না।
এটা PHP ডিফল্ট - এর পরিবর্তে multi-tier-standard অনলাইন প্লে-ব্যাকে তাদের নিজস্ব-কি পলিসি নির্বাচন করুন । আপনার প্যাকেজের একটি কী (key) ব্যবহার করতে হলে আপনার পলিসি অবশ্যই প্যাকেজের চাবি এবং প্রদর্শকের অধিকার সংক্রান্ত পরিবর্তন করতে হবে। কনফিগারেশন অথবা কনফিগারেশনের পরিবর্তন করতে হবে। DRMX_LICENSE_POLICY_TEMPLATE পরিবেশ নির্ধারণের জন্য চিহ্নিত মান উল্লিখিত হয়নি, পরামিতির মধ্যে অনুসন্ধান করা হবে না প্লেয়ারআর- এস ! লাইসেন্স পলিসি.
playback_policy.persistent true করুন এবং license, rental, playback ও renewal-এর মেয়াদ বেছে নিন। Reference-এ যথাক্রমে 7 দিন / 3 দিন / 48 ঘণ্টা / 7 দিন আছে। এগুলো উদাহরণ business rule; studio approval বা platform-wide default নয়। মিল থাকা metadata ফেরত দিন। Widevine license-ই চূড়ান্ত নিয়ন্ত্রণ রাখে।5. Path A: play through DrmXPlayer#
Inside your Activity, create a PlayerView, use a secure window and call prepare after login. The wrapper exchanges the session, configures Widevine, applies the returned maximum height and releases the streaming reservation when stopped. Imports come from com.haihaisoft.drmx.player and AndroidX Media3.
val view = PlayerView(this)
setContentView(view)
DrmXPlayer.protectWindow(window)
val player = DrmXPlayer(this, view)
val capabilities = WidevineCapabilities.playbackCapabilities(
clientPlatform = "android",
displayMetrics = resources.displayMetrics,
applicationVersion = "1.0",
)
player.prepare(
endpoint = "https://customer.example/api/drmx/playback-session",
contentId = "YOUR-PUBLISHED-CONTENT-ID",
contentType = "vod", // use live only for a published live title
capabilities = capabilities,
customerAuthenticationHeaders = mapOf("Authorization" to "Bearer $userToken"),
)
// Keep player as an Activity/Fragment-owned field in your actual application.
// Stop when your playback lifecycle ends; close when the owner is destroyed.
// player.stop()
// player.close()
Western (পশ্চিমি DrmXPlayerListener লেখক, প্রস্তুত, খেলা ও ত্রুটি UIলাইসেন্স টোকেন পাঠের পরিবর্তে নিরাপদ কোড প্রদর্শন করুন । সম্পূর্ণ লাইফ সাইকেল, পূর্ণ পর্দার ছবি নিয়ন্ত্রণ এবং ডাউনলোড করার জন্য ফোন নমুনা ব্যবহার করুন ।
প্লেয়ার নিয়ন্ত্রণ করুন ও আবর্তন#
ট্যাম চালান এই ভিডিও শুরু করতে অনুমোদন করো । পর্দা অথবা বৈশিষ্ট্য চালু করো না যাতে কোনো স্ট্রিমিং লাইসেন্স গ্রহণ করা হয় না । বিরতি বিরতিতে, বৈশিষ্ট্য পরিবর্তন, এবং ফোনের বৈশিষ্ট্য পরিবর্তন, বর্তমান সেশান সংরক্ষণের জন্য বৈশিষ্ট্য সংরক্ষণ করুন ।

| কনট্রোল | ক্রেতারা কি করতে পারে |
|---|---|
| গুণমান | স্বয়ংক্রিয় অথবা সমর্থিত সফ্টওয়্যার নির্বাচন করুন। লাইসেন্সের মান অনুপস্থিত থাকলে, লাইসেন্স অথবা ডিভাইস থেকে প্রাপ্ত করার অনুরোধ জানানো হবে।DRM অগ্রাহ্য করো । স্বয়ংক্রিয়গুলিকে একই বাধা পালন করা হয় । |
| অডিও ট্র্যাক | প্যাকেজ দ্বারা সরবরাহকৃত অডিও ভাষা নির্বাচন করুন। |
| অনুবাদলিপিCC | একটি শিরোনাম বেছে নিন বা বন্ধ করুন । CC বাটন যখন দৃশ্যমান থাকবে এবং তাদের স্বয়ংক্রিয়ভাবে মুছে ফেলা হবে। |
| শিরোনাম | ফন্ট, টেক্সট-এর এবং রং, পটভূমি, রং এবং অস্বচ্ছতার ক্ষেত্রে রঙের বৈশিষ্ট্য ব্যবহার করা হয়। ডিভাইসের মধ্যে পছন্দ সংরক্ষিত আছে। |
| প্লে-ব্যাক গতি বৃদ্ধি করুন | ০.২৫-২ স্বয়ংক্রিয়ভাবে গতি বৃদ্ধি করো অথবা একটি নির্দিষ্ট সময়ের পরে স্বয়ংক্রিয়ভাবে বিরতি দাও। |
| সম্পূর্ণ পর্দা জুড়ে অনুসন্ধান করুন (_F) | টাইম জোন পরিষ্কার করুন, ১০ সেকেন্ড, বা দু'ভাগে সরে যাওয়ার চেষ্টা করুন। পুনরায় চালু না করে ভৌগলিক অবস্থান পরিবর্তন করুন। |
প্রতিটি ভিডিওর মেনুতে Move up / Move down এবং অনলাইনে Download বা অফলাইনে Delete থাকে। ডাউনলোড শেষ হলে Download নিষ্ক্রিয় হয়। Downloaded videos সুইচ দিয়ে অফলাইন প্লেব্যাক বেছে নেওয়া হয়; শুধু ক্যাশে থাকা ট্র্যাক পাওয়া যায়। ডাউনলোড, মুছে ফেলা বা পুরো প্লেলিস্ট ডাউনলোডের আলাদা বোতাম নেই।
লগ কপি করুন বিভিন্ন প্রতিবেদনের সাম্প্রতিক সংস্করণের কপিগুলো ছাড়াও, আপনি একটি স্ক্রিন-শট ছাড়া আরও বিস্তারিত তথ্য পাঠাতে পারেন। রিপোর্টে প্রকাশিত কোনো প্রতিবেদন আছে কিনা তা রিপোর্ট করে। ID- অপারেশন, SDK/Android/dev সংস্করণ, সংখ্যা CDM/Media3 ত্রুটি, নির্বাচিত স্ট্যাক ফ্রেম, সংযোগ/সেকেন্ড অনুযায়ী নির্ধারিত অবস্থা এবং পুনরায় ওয়াদা করা হবে। পরিচয় যাচাইয়ের তথ্যতথ্য, মিডিয়া URL-কি, কি-র ID, লাইসেন্স তথ্য ও সম্পূর্ণ CDM ময়লা.
চিহ্নটি ৩২টি স্থানীয় রিপোর্ট দ্বারা বজায় রাখা হয়েছে (৬৪-৬টি) KB৫ ঘন্টা ধরে সংযুক্ত এবং স্বাক্ষর করার সময়। এটি কনফিগারকৃত কাস্টমার ব্যাক-এন্ডে আপলোড করে থাকে। ৩০ সেকেন্ডের মধ্যে সব সময়ে, অধিকাংশ সময় ধরে পাবলিক ডেমো সার্ভার ৫ ঘন্টা ধরে সতর্ক করে রাখা হয়। KB র্যানন অগ্রগতি এবং সফল প্লেব্যাক লগ করা হয়নি । স্বনির্বাচিত সম্পর্কের মধ্যে অবশ্যই তাদের নিজস্ব সয়ংক্রিয়ভাবে সরবরাহ করতে হবে । drmx.diagnosticsEndpoint; ডায়গনিস্টিক সমস্যা কখনো প্লেব্যাকে বাধা দেয় না ।
val player = DrmXPlayer(this)
val controls = DrmXPlayerView(this)
controls.bind(player) // Does not acquire a session or license.
controls.onPlayRequested = {
player.prepare(endpoint = sessionEndpoint, contentId = contentId,
capabilities = capabilities, customerAuthenticationHeaders = userHeaders)
}
controls.onFullScreenRequested = { /* resize the existing player view */ }
player.listener = object : DrmXPlayerListener {
override fun onAuthorizing(contentId: String) { controls.setPreparing(true) }
override fun onReady(info: DrmXPlaybackInfo) { controls.setPreparing(false) }
override fun onError(error: PlaybackSessionException) { controls.setPreparing(false) }
}
// Keep protectWindow(window) and the secure video surface.
// At final owner destruction: controls.unbind(); player.close()
সরবরাহকৃত ফোন প্রদর্শন নিয়ন্ত্রণ এবং স্ক্রীন সংখ্যা সংক্রান্ত পরিবর্তন; এর বৈশিষ্ট্য onConfigurationChanged একই কর্ম এবং কর্ম পরিবর্তন করুন প্লেয়ারএই অবস্থার সাথে খাপ খাওয়ানোর সময় দুটি অংশ একসাথে রাখুন । এমন একটি হোস্ট যার দ্বারা রিগ্রেশনের মালিক এবং পুনরায় ভিউ নির্ধারণ করা উচিত। স্বাভাবিক অবস্থা পুনরুদ্ধারের জন্য ৪KK / ৮ অপশন প্রয়োজন।DRM সমর্থন; CDM ক্ষমতা এখনো আছে।
স্বনির্বাচিত প্লেয়ারশপথ তাদের , যারা দ ্ রুতগতিতে অগ ্ রসর হয় এবং DRM সেশান পরীক্ষা, পুনর্নবীকরণ অথবা পুনর্নবীকরণের পূর্বে একই ধরনের নিয়মিত লাইসেন্স অনুমোদন করুন। SDK`%s' player.stopForOfflineLicenseOperation { /* call manager here */ } অপেক্ষা করছে Media3 মিডিয়া মুক্ত করার জন্য প্লে-ব্যাক লাইন। stop() যত লাইন অ্যাটলি কাজ করে, আলাদা কিছু করো না checkLicense() যদিও একই লাইসেন্স বাজানো হয়েছে; এটি এখন আরম্ভ করা যাবে CDM উল্লিখিত নমুনাটি পুনর্নবীকরণের সময় সম্পূর্ণ হ্যান্ডঅফ এবং বর্জন করা হবে।
৬) লাইসেন্স সংগ্রহ এবং প্রচার মাধ্যম ডাউনলোড করুন।#
অফলাইন প্লেব্যাকের প্রস্তুতি নিন
সম্পূর্ণ ডাউনলোড এবং ডিভাইসের সঙ্গে যুক্ত বৈধ লাইসেন্স—দুটিই প্রয়োজন।
- এনক্রিপ্ট করা মিডিয়া ডাউনলোড করুন
ইন্টারনেট সংযোগ থাকা অবস্থায় ভিডিও এবং প্রয়োজনীয় অডিও ও সাবটাইটেল ট্র্যাক ডাউনলোড করুন।
- স্থায়ীভাবে সংরক্ষণযোগ্য লাইসেন্স নিন
ইন্টারনেট সংযোগ থাকা অবস্থায় ডিভাইসের সঙ্গে যুক্ত Widevine লাইসেন্স নিন। এর অস্বচ্ছ শনাক্তকারী Key-set ID ব্যক্তিগতভাবে সংরক্ষণ করুন।
- প্রস্তুতি যাচাই করুন
ডাউনলোড সম্পূর্ণ হয়েছে এবং লাইসেন্স বৈধ আছে কি না নিশ্চিত করুন।
- অফলাইনে চালান
ক্যাশে থাকা মিডিয়া পড়ুন এবং স্থানীয় লাইসেন্স পুনরুদ্ধার করুন। নবায়ন ও লাইসেন্স মুক্ত করতে ইন্টারনেট সংযোগ প্রয়োজন।
val offlineManager = DrmXOfflineManager(applicationContext)
val capabilities = WidevineCapabilities.offlinePlaybackCapabilities(
clientPlatform = "android", // android-tv or android-automotive where applicable
displayMetrics = resources.displayMetrics,
applicationVersion = "1.0",
)
offlineManager.acquireLicense(
endpoint = offlineEndpoint,
contentId = contentId,
capabilities = capabilities,
customerAuthenticationHeaders = customerHeaders,
) { result ->
result.onSuccess { stored ->
// Next: select tracks <= stored.maximumHeight and queue their download.
// Acquisition alone does not download the video.
}.onFailure { /* show a safe retry/error state */ }
}
এটা SDK অস্বচ্ছতা সংরক্ষণ করা হবে Widevine কি-রিং ID এবং গোপন মিটা-ডাটা। CDM লাইসেন্স ধারণ করে, এটা আর সহ্য করা যাবে না DRM License Tokens, raw কি, চ্যালেঞ্জ অথবা লাইসেন্স প্রতিক্রিয়া প্রাপ্ত হয়েছে। com.haihaisoft.drmx.offline.licenses.v1.xml ব্যাকআপ থেকে.
একটি অ্যাপ্লিকেশন নির্মাণ করুন Media3 SimpleCacheডাউনলোড এবং ডাটাবেস ডাউনলোড করুন। DownloadHelper লাইসেন্স মিডিয়া বিষয়বস্তু সহ এবং ভিডিও নির্বাচন করুন maximumHeightইন ইন ! Media3 ১.১১ প্রস্তুতকারী কল-ব্যাক হচ্ছে onPrepared(helper, tracksInfoUpdated)ফোন নমুনা enqueueDownload এবং OfflineTestRuntime কার্যকরী বাস্তবায়ন ব্যবস্থা প্রদর্শন করা হবে ।
// Inside DownloadHelper's prepared callback, after selecting licensed video:
helper.addAudioLanguagesToSelection("en", "zh-Hans", "zh")
helper.addTextLanguagesToSelection(true, "en", "zh-Hans", "zh")
val selected = helper.getDownloadRequest(offlineLicenseId, byteArrayOf())
val request = offlineManager.createDownloadRequest(contentId, selected.streamKeys)
downloadManager.addDownload(request)
helper.release()
প্রতিটি ভাষা ডাউনলোড করুন যাতে অফ-লাইন মুছে ফেলা যায়। createDownloadRequest কি-র সকল রেকর্ড বিনা স্ট্রিম ডাউনলোড করা হবে, যা সাধারণত খাপ খাইয়ে নেওয়া হয়। ডাউনলোড করে প্রগতির জন্য অপেক্ষা করুন। Download.STATE_COMPLETEDসাবস্ক্রাইব করার জন্য ব্যাক- ট্রেস স্থানান্তর করা, বিনিময়ের জন্য Media3 DownloadServiceসম ্ মানিত , গুণান ্ নিত । Android অগ্রভূমির জন্য সংরক্ষিত /notification- র জন্য প্রয়োজনীয়; ডেমো লাইন প্রতিরোধ ব্যবস্থায় চলছে ।
৭. পাথ B: আপনার বিদ্যমান বিদ্যমান অবস্থায় পুনরুদ্ধার করুন Media3 প্লেয়ার#
সম্পূর্ণ ডাউনলোড এবং তার সঠিক স্ট্রিম কি ব্যবহার করে ডাউনলোড করা হবে। ডাউনলোড এবং প্লে-ব্যাকটি ডিস্কের অবস্থান এবং কি-র সাহায্যে একই ক্যাশে থেকে স্থান শেয়ার করা আবশ্যক। উদাহরণ:
val cacheOnly = CacheDataSource.Factory()
.setCache(downloadCache)
.setUpstreamDataSourceFactory(null)
val mediaSourceFactory = DefaultMediaSourceFactory(this)
.setDataSourceFactory(cacheOnly)
val nativePlayer = ExoPlayer.Builder(this)
.setMediaSourceFactory(mediaSourceFactory)
.build()
val completed = downloadIndex.getDownload(offlineLicenseId)
require(completed?.state == Download.STATE_COMPLETED)
val playback = offlineManager.createPlayback(contentId, streamKeys = completed!!.request.streamKeys)
nativePlayer.setMediaItem(playback.mediaItem)
nativePlayer.prepare()
nativePlayer.play()
// Release nativePlayer when the owner is destroyed.
পাথ দিয়ে একই প্রান্তীয় বিন্দু ব্যবহার করে DrmXPlayer এই দিয়ে mediaSourceFactory কল player.prepareOffline(playback)সাধারণ পুনর্স্থাপন স্থানীয় সময় CDM কোনো নতুন অ্যাকাউন্ট অনুরোধ না করে লাইসেন্স প্রাপ্ত করার ফলে সমস্যা দেখা দিতে পারে।
৮. পাথ: Media3না DRM-X AAR#
আপনাকে DrmXPlayer বা DrmXOfflineManager ব্যবহার করার প্রয়োজন নেই। ধাপ 3 থেকে তিনটি Media3 নির্ভরতা যোগ করুন এবং একই গ্রাহক ব্যাকএন্ড চুক্তি বাস্তবায়ন করুন। session.manifestUrl (session.manifest.url নয়), ফিরে আসা লাইসেন্স URL এবং স্বল্পস্থায়ী অনুমোদনের শিরোনাম ব্যবহার করুন। প্রত্যাবর্তিত সর্বোচ্চ উচ্চতা প্রয়োগ করুন এবং স্টপ, প্রতিস্থাপন, শেষ, ব্যর্থতা এবং ধ্বংসের উপর স্ট্রিমিং সেশন রিলিজ পরিচালনা করুন।
নীচের এই স্থানীয় কর্ম সম্পূর্ণ হয়েছে samples:native এই সাথে SDK ছেড়ে দিন। HTTPSঅনুমোদনকৃত জবাব, পটভূমি অনুমোদন, অবিকৃত উত্তর এবং সন্দেহাতীত উত্তর। চিহ্নিত চিহ্নটি চিহ্নিত/আউটআউটে প্রতিস্থাপন করা হবে।Content ID আপনার নিজস্ব লগ-ইন টোকেন সরবরাহ করুন। উদাহরণ হলো শুরু করা যায়; আপনার উৎপাদনশীলতা, হিসাব-বিদ্যুৎ এবং অ্যাপনাইজিং লাইফসাইকেল যোগ করুন।
সম্প্রচার সম্পূর্ণ হচ্ছে (সম্পন্ন স্ট্রিম)Kotlinনা DRM-X নির্ভরতা
package com.haihaisoft.drmx.samples.nativeplayer
import android.app.Activity
import android.os.Bundle
import android.view.WindowManager
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.ui.PlayerView
import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URI
import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean
/** Complete native streaming example. No DRM-X AAR or server credentials. */
@UnstableApi
class MainActivity : Activity() {
private lateinit var player: ExoPlayer
private lateinit var status: TextView
private val worker = Executors.newSingleThreadExecutor()
private val closed = AtomicBoolean(false)
private var activeSession: JSONObject? = null
private var requesting = false
private var generation = 0
// CUSTOMIZE: use YOUR authenticated customer backend and Published Content ID.
// The sample can receive these after your application's login via Intent extras.
// Never replace the app login token with a DRM-X Site Key or Access Key.
private val endpoint get() = intent.getStringExtra("drmx.sessionEndpoint")
?: "https://customer.example/api/drmx/playback-session"
private val contentId get() = intent.getStringExtra("drmx.contentId") ?: "YOUR-PUBLISHED-CONTENT-ID"
private val customerToken get() = intent.getStringExtra("customer.accessToken").orEmpty()
override fun onCreate(state: Bundle?) {
super.onCreate(state)
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
val root = LinearLayout(this).apply { orientation = LinearLayout.VERTICAL; fitsSystemWindows = true; setPadding(24, 24, 24, 24) }
status = TextView(this).apply { text = "Native Media3 · connect your backend, then Play"; textSize = 16f }
val view = PlayerView(this)
player = ExoPlayer.Builder(this).build(); view.player = player
root.addView(status)
root.addView(view, LinearLayout.LayoutParams(-1, 0, 1f))
root.addView(Button(this).apply { text = "Play protected video"; setOnClickListener { startPlayback() } })
root.addView(Button(this).apply { text = "Stop & release session"; setOnClickListener { stopPlayback() } })
setContentView(root)
player.addListener(object : Player.Listener {
override fun onPlayerError(error: PlaybackException) { status.text = "Playback error: ${error.errorCodeName}"; releaseSession() }
override fun onPlaybackStateChanged(state: Int) { if (state == Player.STATE_ENDED) releaseSession() }
})
}
private fun startPlayback() {
if (requesting) return
stopPlayback(); requesting = true; status.text = "Authorizing…"
val attempt = generation
val request = JSONObject().put("contentId", contentId).put("contentType", "vod")
.put("drmSystem", "widevine").put("playbackMode", "streaming")
.put("platformCapabilities", JSONObject().put("clientPlatform", "android")
.put("drmSystems", org.json.JSONArray(listOf("widevine")))
.put("manifestTypes", org.json.JSONArray(listOf("dash")))
.put("maximumHeight", 1080).put("secureDecoder", false).put("persistentState", false))
val headers = if (customerToken.isBlank()) emptyMap() else mapOf("Authorization" to "Bearer $customerToken")
worker.execute {
val result = runCatching { JSONObject(post(endpoint, request.toString(), headers)) }
runOnUiThread {
requesting = false
result.onSuccess { session ->
if (closed.get() || attempt != generation) { workerRelease(session); return@onSuccess }
// Keep release information even if contract validation fails.
activeSession = session
runCatching {
require(session.getInt("contractVersion") == 1 && session.getString("contentId") == contentId)
require(session.getString("drmSystem") == "widevine" && session.getString("playbackMode") == "streaming")
val drm = session.getJSONObject("drm")
require(drm.getString("system") == "widevine")
val maximumHeight = session.getJSONObject("policy").getInt("maximumHeight")
require(maximumHeight in 1..4320)
val mediaItem = MediaItem.Builder().setUri(https(session.getString("manifestUrl")))
.setMimeType("application/dash+xml")
.setDrmConfiguration(MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
.setLicenseUri(https(drm.getString("licenseServerUrl")))
.setForceDefaultLicenseUri(true).setLicenseRequestHeaders(authorization(drm))
.setMultiSession(false).build()).build()
player.trackSelectionParameters = player.trackSelectionParameters.buildUpon()
.setMaxVideoSize(Int.MAX_VALUE, maximumHeight).setPreferredAudioLanguages("en")
.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, true).build()
player.setMediaItem(mediaItem); player.prepare(); player.play()
status.text = "Native Media3 · protected playback"
}.onFailure { status.text = "Invalid session contract. Check your backend."; releaseSession() }
}.onFailure { if (!closed.get()) status.text = "Authorization failed. Check login, Content ID, policy, and network." }
}
}
}
private fun releaseSession() { activeSession?.let(::workerRelease); activeSession = null }
private fun workerRelease(session: JSONObject) {
// A bounded release may finish after Activity destruction, including a
// session response that arrived after the user left the screen.
Thread({ runCatching {
val release = session.getJSONObject("release")
val headers = if (release.has("authorization")) authorization(release)
else authorization(session.getJSONObject("drm"))
post(release.getString("url"), "", headers)
} }, "drmx-native-release").start()
}
private fun stopPlayback() { generation++; player.stop(); player.clearMediaItems(); releaseSession() }
override fun onStop() { stopPlayback(); super.onStop() }
override fun onDestroy() { closed.set(true); stopPlayback(); player.release(); worker.shutdown(); super.onDestroy() }
companion object {
fun https(url: String): String {
val uri = URI(url); require(uri.scheme == "https" && uri.host != null && uri.userInfo == null)
return url
}
fun authorization(drm: JSONObject): Map<String, String> {
val auth = drm.optJSONObject("authorization")
val name = auth?.getString("headerName") ?: "Authorization"
val scheme = auth?.getString("scheme") ?: drm.optString("tokenType", "Bearer")
val value = auth?.getString("value") ?: drm.getString("drmLicenseToken")
require(name.matches(Regex("^[A-Za-z0-9-]{1,64}$")) && scheme.matches(Regex("^[A-Za-z][A-Za-z0-9._-]{0,31}$")))
require(value.isNotBlank() && !value.contains('\r') && !value.contains('\n'))
return mapOf(name to "$scheme $value")
}
fun post(url: String, body: String, headers: Map<String, String>): String {
val connection = URI(https(url)).toURL().openConnection() as HttpURLConnection
try {
connection.requestMethod = "POST"; connection.instanceFollowRedirects = false
connection.connectTimeout = 5000; connection.readTimeout = 15000; connection.doOutput = true
connection.setRequestProperty("Content-Type", "application/json")
headers.forEach { (name, value) -> connection.setRequestProperty(name, value) }
connection.outputStream.use { it.write(body.toByteArray(Charsets.UTF_8)) }
require(connection.responseCode in 200..299) { "Customer request rejected" }
return connection.inputStream.use { stream ->
val output = java.io.ByteArrayOutputStream(); val buffer = ByteArray(8192)
while (true) {
val count = stream.read(buffer); if (count < 0) break
require(output.size() + count <= 1_048_576); output.write(buffer, 0, count)
}
output.toString("UTF-8")
}
} finally { connection.disconnect() }
}
}
}
স্থানীয় অফ-লাইন লাইসেন্সের জন্য, ব্যবহারের জন্য OfflineLicenseHelper.downloadLicenseএর উপরে যারাই আছে তা বিনাশশীল , ID ব্যক্তিগত তথ্যসহ এবং পুনরুদ্ধার MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID).setKeySetId(id)নিম্নলিখিত কম্পাইলকৃত সাহায্যাদিাদিাদি, পরীক্ষা, পুনঃনির্মাণ, এবং ডাউনলোড করুন। এটি হতে পারে। একটি সম্পূর্ণ ডাউনলোড প্রক্রিয়া সম্পন্ন না: আপনি এখনো ক্যাশ-এর মালিক, ডাউনলোড পরিষেবা, উন্নতি, মিটা-ডাটা, ব্যবহারকারী/device- id এবং বিশ্বস্ত অপারেশন অনুমোদন।
স্থানীয় স্থায়ী সহায়ক (ইচ্ছাকৃত সহায়ক)Kotlinনা DRM-X নির্ভরতা
package com.haihaisoft.drmx.samples.nativeplayer
import android.content.Context
import android.util.Base64
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.StreamKey
import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.exoplayer.dash.DashUtil
import androidx.media3.exoplayer.drm.DrmSessionEventListener
import androidx.media3.exoplayer.drm.OfflineLicenseHelper
import androidx.media3.exoplayer.offline.DownloadRequest
import org.json.JSONObject
/** Native Media3 alternative: no DRM-X AAR. Call blocking operations on a worker.
* Application owns downloads/cache, user/device entitlement, progress and lifecycle.
* Never persist the session, request headers, tokens, challenges or license bytes.
*/
@UnstableApi
class NativeOfflineLicense(context: Context) {
private val storage = context.getSharedPreferences("native.offline.keysets", Context.MODE_PRIVATE)
private val upstream = DefaultHttpDataSource.Factory().setConnectTimeoutMs(10000).setReadTimeoutMs(20000)
// session is the validated response from YOUR offline-license-session endpoint.
fun acquire(session: JSONObject): ByteArray {
validate(session)
val contentId = session.getString("contentId")
require(!storage.contains(contentId)) { "Renew or release the stored license before acquiring again" }
val source = upstream.createDataSource()
val manifest = DashUtil.loadManifest(source, android.net.Uri.parse(MainActivity.https(session.getString("manifestUrl"))))
val format = DashUtil.loadFormatWithDrmInitData(upstream.createDataSource(), manifest.getPeriod(0))
?: error("Missing Widevine initialization data")
val helper = helper(session)
try {
val id = helper.downloadLicense(format)
save(contentId, id)
return id
} finally { helper.release() }
}
fun renew(contentId: String, freshSession: JSONObject) {
validate(freshSession); require(freshSession.getString("contentId") == contentId)
val helper = helper(freshSession)
try { save(contentId, helper.renewLicense(keySet(contentId))) } finally { helper.release() }
}
// Local CDM check only. No token or network license URI is used.
fun remainingSeconds(contentId: String): Pair<Long, Long> {
val config = MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID).build()
val helper = OfflineLicenseHelper.newWidevineInstance(config, upstream, DrmSessionEventListener.EventDispatcher())
try {
val remaining = helper.getLicenseDurationRemainingSec(keySet(contentId))
return Pair(remaining.first, remaining.second)
} finally { helper.release() }
}
fun release(contentId: String, freshSession: JSONObject) {
validate(freshSession); require(freshSession.getString("contentId") == contentId)
val helper = helper(freshSession)
try {
helper.releaseLicense(keySet(contentId))
check(storage.edit().remove(contentId).commit())
} finally { helper.release() }
}
fun downloadRequest(contentId: String, downloadId: String, manifestUrl: String, streamKeys: List<StreamKey>): DownloadRequest {
require(streamKeys.isNotEmpty()) { "Select policy-compliant video, audio and subtitle tracks first" }
return DownloadRequest.Builder(downloadId, android.net.Uri.parse(MainActivity.https(manifestUrl)))
.setMimeType("application/dash+xml").setStreamKeys(streamKeys).setKeySetId(keySet(contentId)).build()
}
fun mediaItem(contentId: String, manifestUrl: String, streamKeys: List<StreamKey>): MediaItem = MediaItem.Builder()
.setUri(MainActivity.https(manifestUrl)).setMimeType("application/dash+xml").setStreamKeys(streamKeys)
.setDrmConfiguration(MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID).setKeySetId(keySet(contentId)).build()).build()
private fun helper(session: JSONObject): OfflineLicenseHelper {
val drm = session.getJSONObject("drm")
// Use HTTP license headers, NOT Widevine optional key-request parameters.
val config = MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
.setLicenseUri(MainActivity.https(drm.getString("licenseServerUrl")))
.setForceDefaultLicenseUri(true).setLicenseRequestHeaders(MainActivity.authorization(drm)).build()
return OfflineLicenseHelper.newWidevineInstance(config, upstream, DrmSessionEventListener.EventDispatcher())
}
private fun validate(session: JSONObject) {
require(session.getInt("contractVersion") == 1 && session.getString("playbackMode") == "offline")
require(session.getString("drmSystem") == "widevine" && session.getString("contentType") == "vod")
require(session.getJSONObject("policy").getBoolean("persistent"))
}
private fun keySet(contentId: String): ByteArray = Base64.decode(storage.getString(contentId, null)
?: error("No device-bound license for this content"), Base64.NO_WRAP)
private fun save(contentId: String, id: ByteArray) {
check(storage.edit().putString(contentId, Base64.encodeToString(id, Base64.NO_WRAP)).commit())
}
}
এই উচ্চ পর্যায়ের সহায়তা করার পূর্বে, চিহ্নিত ব্যাক-এন্ড সমর্থনের পূর্বে একটি নতুন ব্যাক-এন্ড যোগ করা হবে Content IDঅপারেশন, স্বাক্ষরিত ব্যবহারকারী/device-interid এবং অনুমোদন ব্যবস্থার বৈধতা যাচাই এবং অনুমোদন। একটি স্থায়ী অফলাইনLCTCTEDC-র সাহায্যে বিশ্বস্ত মিটা-ডাটার সাহায্যে বিশ্বাস করা হয়। IDকোন টোকেন নয়, কর্মচারীর থ্রেডে অভিযান চালানো, লাইসেন্সের জন্য আহ্বান জানানো। HTTP হেডার ব্যবহার করা হবে setLicenseRequestHeaders এর উপর DRM কনফিগারেশন; Widevine ঐচ্ছিক কি-রিংয়ের পরামিতি একটি ভিন্ন ম্যাপ।
New integrations should use AndroidX Media3 DRM support. Legacy com.google.android.exoplayer2 projects should follow the official migration guide; do not mix legacy and AndroidX classes or assume the sample compiles unchanged against older versions.
পরীক্ষা করুন, পুনর্মূল্যায়ন, মুক্ত এবং লগ-ইন করুন#
These are separate actions. Run one at a time after the active offline DRM session has been released: use player.stopForOfflineLicenseOperation { /* one operation below */ } with DrmXPlayer, or release the existing native Media3 player first. Do not check a license while it is playing. A check is optional for displaying durations; it must not prevent renewal of an expired license.
offlineManager.checkLicense(contentId) { result ->
result.onSuccess { license ->
if (license.state == DrmXOfflineLicenseState.EXPIRED) {
// Require renewal online before offering offline playback.
}
}
}
offlineManager.renewLicense(offlineEndpoint, contentId, capabilities, customerHeaders) {
/* update duration and UI after success; show retry on failure */
}
// Only when the customer requests deletion/release:
offlineManager.releaseLicense(offlineEndpoint, contentId, capabilities, customerHeaders) {
/* after success, remove the corresponding encrypted download */
}
getStoredLicense মিটা-ডাটা পড়া হচ্ছে; checkLicense স্থানীয় অবস্থান পরিদর্শন করুন CDM অবকাল। নতুন করে যোগাযোগ করুন এবং আপনার ব্যাক-আপ থেকে একটি নতুন কর্ম সংক্রান্ত সংরক্ষিত অনুমোদন প্রয়োজন। মিডিয়া মুছে ফেলা হলে লাইসেন্সটি প্রত্যাহার করা হবে না। বন্ধ করা হলে সার্ভার দ্বারা এই ব্যবস্থাপনার অনুমতি প্রদান করা হবে।
// Use player.media3Player for the DRM-X wrapper; nativePlayer for plain Media3.
nativePlayer.trackSelectionParameters = nativePlayer.trackSelectionParameters
.buildUpon()
.setPreferredAudioLanguages("en") // Chinese: "zh-Hans", "zh"
.setPreferredTextLanguages("en") // choose a packaged/downloaded language
.setTrackTypeDisabled(C.TRACK_TYPE_TEXT, false) // true = subtitles Off
.build()
প্রকৃত উপলব্ধ স্থান থেকে নির্বাচন করুন ও উপলব্ধ নির্বাচন না করা পছন্দসই মান সরিয়ে ফেলা যাবে। কোনো পছন্দ না করা হলে, প্যাকেজ থেকে ইংরেজী ট্র্যাক অনুপস্থিত থাকতে পারে। অফলাইন ব্যবহারকারীরা পর্দার সম্পূর্ণ পর্দার ছবি প্রদর্শন করা হবে, কোনো বিকল্প দ্বারা অন্য লাইসেন্স গ্রহণ করা হবে না।
অফ-লাইন সমাপ্তির অধিকার প্রদান করা হবে।#
এই অ্যাপ্লিকেশনের পোস্ট contentId, contentType: "vod", drmSystem: "widevine", playbackMode: "offline", operation: "acquire" | "renew" | "release", offlineLicenseId ( প্রাথমিক অর্জন এবং সত্য) platformCapabilitiesযাচাই করুন যে অনুমোদিত ব্যবহারকারী, ডিভাইস এবং বিষয়বস্তুর ক্ষেত্রে নতুন ব্যবহারকারীর ID খুঁজে বের করার জন্য অনুমোদিত ব্যবহারকারীর পরিচয় প্রমাণ করুন। DRM License Token এবং চুক্তিবদ্ধ চুক্তিটি ফেরত দাও:
{
"contractVersion": 1, "playbackMode": "offline",
"offlineLicenseId": "YOUR-STABLE-USER-DEVICE-CONTENT-RECORD",
"contentId": "YOUR-PUBLISHED-CONTENT-ID", "contentType": "vod",
"drmSystem": "widevine",
"manifestUrl": "https://media.customer.example/title/manifest.mpd",
"authorizationExpiresAt": "YOUR-FRESH-UTC-EXPIRY",
"drm": {
"system": "widevine",
"licenseServerUrl": "https://license6.drm-x.com/v1/licenses/widevine",
"integrationMode": "direct-token",
"drmLicenseToken": "SHORT-LIVED-OPERATION-AUTHORIZATION",
"tokenType": "Bearer"
},
"policy": {
"persistent": true, "renewAllowed": true, "maximumHeight": 1080,
"allowedTrackTypes": ["AUDIO", "SD", "HD"],
"licenseDurationSeconds": 604800, "rentalDurationSeconds": 259200,
"playbackDurationSeconds": 172800, "renewalDurationSeconds": 604800
}
}
এই পরিদর্শনগুলো প্রকৃত অপারেশনের থেকে নতুন মান ফিরিয়ে দেয় । SDK এছাড়াও সমর্থন integrationMode: "token-proxy" এবং সুষ ্ ঠু-সুন ্ দর বিষয়ে সত ্ যনিষ ্ ঠ থাকে , drm.authorization ডেক্ল্যান, ফিরে এসো। Cache-Control: no-store; লগ- ইন সফল অনুমোদন তালিকা পাওয়া যায়নি । ডাউনলোড করা যাবে না SDK`%s' OFFLINE_INTEGRATION.md এবং PHP কনস্টেবল ব্যবস্থাপনার অনুরোধের সমাপ্তি নিশ্চিত করা হয়েছে
আপনার যন্ত্র এবং সমস্যা সমাধান করুন#
| / আদম (general) | প্রত্যাশিত আচরণ / পরবর্তী পরীক্ষা করা হবে |
|---|---|
| SDK ৪০৩ ফেরত ডাউনলোড | সক্রিয় পেশাদারী অথবা এন্টারপ্রাইজ সাবস্ক্রিপশন সহ একটি সংগঠন নির্বাচন করুন । বিচারের পর একটা পরিকল্পনা সফল হয় SDKকে না জানিয়ে। |
| সেশন ৪০১ / ৪০৩ | লগ- ইন করুন, আরম্ভ করা হবে, পরিবেশ, ঘোষণা Content ID এবং নীতি, কখনো আমাদের অনুমোদন নেই। |
| অফ-লাইন অবস্থায় কর্ম বাতিল করা হবে | পরীক্ষা করুন CDM দৈর্ঘ্য, ডাউনলোড, ক্যাশ, চাবি, এবং সকল সার্বজনীন কি দ্বারা নির্ধারিত হয়েছে। |
| ইংরেজি/ চাইনিজ অনুপস্থিত | প্যাকেজের ভাষার মিটা-ডাটা, প্রকৃত ট্র্যাক এবং অফলাইন নির্বাচন করা হবে। |
| L1, HDCP ডি-কোড করতে ব্যর্থ | শারীরিক হার্ডওয়্যার পরীক্ষা করুন, বাইনারি ও আউটপুট প্রয়োজনীয়তা পরীক্ষা করুন। এর ফলে কর্মক্ষমতা হ্রাস পায় না। |
| পুনরারম্ভ, আবর্তন ও আপগ্রেড | Pleasst লাইসেন্স ও ক্যাশে অনুরূপভাবে জীবন চক্রের পরিবর্তন সমর্থন করে। ব্যাক- আপ করতে হলে নতুন ডিভাইসের ক্ষেত্রে লাইসেন্সের পরিমাণ পরিবর্তন করা উচিত নয়। |
| গ্রহার মোড | এক্স-ফাই এবং মোবাইল ডাটাও নিষ্ক্রিয় করুন; অ্যাপ্লিকেশনটি স্থানীয় ভাবে চালু করুন এবং প্রত্যেক প্রতিশ্রুতির ভাষা পরিবর্তন করুন। |
| মেয়াদপূর্তী, সংগ্রহস্থলের চাপ, অ্যাকাউন্ট পরিবর্তন সংক্রান্ত বিকল্প | পরিষ্কার/নতুন অবস্থা প্রদর্শন করুন, অসম্পূর্ণ মিডিয়া পুনরুদ্ধার করুন এবং ব্যবহারকারী দ্বারা ব্যবহারকারীর/ডিভাইস নিবন্ধন না করে ব্যবহারকারীর অবস্থান সম্পর্কে তথ্য প্রদর্শন করা হবে। |
প্রতিটি সমর্থিত ফোন, ট্যাবলেট, Android TV/Google TV, Fire TV সন্নিবেশিত Android মডেল Widevine/ নিরাপদ decoting, codec/reated, HDCPবহিস্থিত প্রদর্শন, ঘড়ির পরিবর্তন, পরিবর্তন ও দীর্ঘ সময় ধরে সংযোগ স্থাপন করা হবে। Android ডিভাইসের মধ্যে উপস্থিত আছে DRM হলিউডের বিষয়বস্তুর জন্য অধিকার ধরে রাখা প্রয়োজন এবং ডিভাইস প্রয়োজনীয় চাহিদা, কেবল সফল ভাবে বন্ধ করা নয়।
Universal Player-এর প্লেলিস্ট ও অভিন্ন কন্ট্রোল#
Android ও Apple প্লেয়ারে Previous/Play-Pause/Next, CC, Settings ও পূর্ণপর্দার নিয়ন্ত্রণ রয়েছে। Move up / Move down বর্তমান ভিডিও বজায় রেখে অনলাইন ও অফলাইন প্লেব্যাকের জন্য তালিকার ক্রম সংরক্ষণ করে। অ্যাপ আবার খুললেও এলোমেলো ও পুনরাবৃত্ত প্লেব্যাকের নির্বাচন বজায় থাকে; দুটোই বন্ধ থাকলে শেষ আইটেমের পরে প্লেব্যাক থামে।
একই গ্রাহক/অনুক্রমকারী storageNamespace চিহ্নিত স্থানে চলুন DrmXPlayer এবং playerView.storageNamespace প্লে-লিস্ট নির্ধারণের পূর্বে VOD অগ্রগতি সংরক্ষিত হয়েছে এবং স্থগিত রাখা হয়েছে, তারপর পুনরায় ফিরে যাওয়া হবে Content ID স্ট্রিম অথবা ডাউনলোড করা হচ্ছে। প্লে-ব্যাকের মধ্যে প্লে-ব্যাক সংরক্ষণ করা হবে না। VOD অবস্থান অনুযায়ী ডাউনলোড করা হয়। নেটওয়ার্ক মিডিয়া বিনা এই ডিভাইসটি দ্বারা সুসংগত নয়। নেটওয়ার্কের মধ্যে উপস্থিত অন্যান্য সফ্টওয়্যারের সাথে সুসংগত নয়।
Web ও Android একই গাঢ় প্যানেল ও ছোট নীল কন্ট্রোল ব্যবহার করে। পরের/আগের, এলোমেলো, এক/সব পুনরাবৃত্তি ও বাতিলযোগ্য স্বয়ংক্রিয় অগ্রগতি আছে। প্রতি আইটেমে নতুন অনুমোদন চাওয়া হয়। অধ্যায় ও প্রতিলিপি আসে কনটেন্ট ক্যাটালগ থেকে।
গতি, ঘুমের টাইমার, সাবটাইটেল, অনুমোদিত মান, অডিও ভাষা, সেশন বুকমার্ক ও A–B লুপ আছে। Web-এ শর্টকাট, দর্শকভিত্তিক ঐচ্ছিক স্থানীয় পুনরায় শুরু, প্রতিলিপি খোঁজা ও সমর্থিত PiP আছে। Android নেটিভ Widevine অফলাইন ডাউনলোড ও নবায়ন রাখে। অন্য পর্দায় কাস্ট ও ডিভাইসভিত্তিক অগ্রগতি মেলাতে আলাদা ইন্টিগ্রেশন লাগে।
পেশা ও এন্টারপ্রাইজ লোগো সেটিংস
ব্র্যান্ডিং ভিডিও পৃষ্ঠ থেকে পড়ে থাকবে । খোলা মান ক্সি সম্পর্কিত তথ্য খোলা প্লেয়ার অনুমোদিত লোগো, পণ্য তথ্য এবং তথ্য প্লেয়ার ওয়েবের মাধ্যমে এই তথ্য ডান ক্লিকের মাধ্যমে প্রদান করা হয়েছে।
বিশ্বস্ত ব্যাকএন্ডে playerBranding-কে {"mode":"hidden"} বা {"mode":"custom","logoUrl":"https://your-site.example/logo.png","label":"Your brand"} দিন। সক্রিয় Professional বা Enterprise যাচাই হয়। অন্য প্ল্যানে {"mode":"default"}; অনুমতিহীন কাস্টম/লুকানো অনুরোধে 403 ফেরে। এটি নিরাপত্তা ওয়াটারমার্ক থেকে আলাদা।
PHP ডাউনলোডে বদলানো যায় এমন প্লেলিস্ট ও ব্র্যান্ডিং আছে। Android ZIP-এ কলব্যাক উদাহরণ আছে। প্লেলিস্ট অনুমোদন ব্যাকএন্ডে রাখুন; কোনো প্লেয়ারে API ক্লায়েন্টের প্রমাণীকরণ তথ্য ঢোকাবেন না।
DRM-X 6.0