Comments (4)
yes ... this is my code (i'm not an android developer)
CustomDashManifestParser file:
import android.text.TextUtils;
import android.util.Base64;
import android.util.Pair;
import androidx.media3.common.C;
import androidx.media3.common.DrmInitData.SchemeData;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.NullableType;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.XmlPullParserUtil;
import androidx.media3.exoplayer.dash.manifest.DashManifestParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.UUID;
import androidx.media3.extractor.mp4.PsshAtomUtil;
import com.google.common.base.Ascii;
@UnstableApi @SuppressWarnings("NullableOnContainingClass")
public final class CustomDashManifestParser extends DashManifestParser {
private final DashManifestParser defaultParser = new DashManifestParser();
private String defaultKid_global = "";
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
public CustomDashManifestParser(String kid) {
if (kid.length() == 32) {
byte[] data = hexStringToByteArray(kid);
defaultKid_global = new UUID(ByteBuffer.wrap(data, 0, 8).getLong(), ByteBuffer.wrap(data, 8, 8).getLong()).toString();
}
}
@Override
protected Pair<@NullableType String, @NullableType SchemeData> parseContentProtection(
XmlPullParser xpp) throws XmlPullParserException, IOException {
String schemeType = null;
String licenseServerUrl = null;
byte[] data = null;
UUID uuid = null;
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
if (schemeIdUri != null) {
switch (Ascii.toLowerCase(schemeIdUri)) {
case "urn:mpeg:dash:mp4protection:2011":
schemeType = xpp.getAttributeValue(null, "value");
String defaultKid = XmlPullParserUtil.getAttributeValueIgnorePrefix(xpp, "default_KID");
if (TextUtils.isEmpty(defaultKid) || "00000000-0000-0000-0000-000000000000".equals(defaultKid) && !"".equals(defaultKid_global)){
defaultKid = defaultKid_global;
}
String[] defaultKidStrings = defaultKid.split("\\s+");
UUID[] defaultKids = new UUID[defaultKidStrings.length];
for (int i = 0; i < defaultKidStrings.length; i++) {
defaultKids[i] = UUID.fromString(defaultKidStrings[i]);
}
data = PsshAtomUtil.buildPsshAtom(C.COMMON_PSSH_UUID, defaultKids, null);
uuid = C.COMMON_PSSH_UUID;
break;
case "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":
uuid = C.PLAYREADY_UUID;
break;
case "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":
uuid = C.WIDEVINE_UUID;
break;
case "urn:uuid:e2719d58-a985-b3c9-781a-b030af78d30e":
uuid = C.CLEARKEY_UUID;
break;
default:
break;
}
}
do {
xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "clearkey:Laurl") && xpp.next() == XmlPullParser.TEXT) {
licenseServerUrl = xpp.getText();
} else if (XmlPullParserUtil.isStartTag(xpp, "ms:laurl")) {
licenseServerUrl = xpp.getAttributeValue(null, "licenseUrl");
} else if (data == null
&& XmlPullParserUtil.isStartTagIgnorePrefix(xpp, "pssh")
&& xpp.next() == XmlPullParser.TEXT) {
// The cenc:pssh element is defined in 23001-7:2015.
data = Base64.decode(xpp.getText(), Base64.DEFAULT);
uuid = PsshAtomUtil.parseUuid(data);
if (uuid == null) {
data = null;
}
} else if (data == null
&& C.PLAYREADY_UUID.equals(uuid)
&& XmlPullParserUtil.isStartTag(xpp, "mspr:pro")
&& xpp.next() == XmlPullParser.TEXT) {
// The mspr:pro element is defined in DASH Content Protection using Microsoft PlayReady.
data =
PsshAtomUtil.buildPsshAtom(
C.PLAYREADY_UUID, Base64.decode(xpp.getText(), Base64.DEFAULT));
} else {
//maybeSkipTag(xpp);
}
} while (!XmlPullParserUtil.isEndTag(xpp, "ContentProtection"));
SchemeData schemeData =
uuid != null ? new SchemeData(uuid, licenseServerUrl, MimeTypes.VIDEO_MP4, data) : null;
return Pair.create(schemeType, schemeData);
}
}
and on playeractivity add setManifestParser(CustomDashManifestParser(channel.kid))
player = ExoPlayer.Builder(this)
.setTrackSelector(trackSelector!!)
.setMediaSourceFactory(
DashMediaSource.Factory(
DefaultDashChunkSource.Factory(dataSourceFactory),
dataSourceFactory
).setManifestParser(CustomDashManifestParser(channel.kid))
.setDrmSessionManagerProvider { clearkeyDrmSessionManager }
)
.build()
from media.
Thank you for your report. It seems to me like a duplicate of: google/ExoPlayer#9169, #563, #780, #777 (comment)
TLDR: it might have something to do with your ContentProtection
node missing default_KID
which is required as per: https://dashif-documents.azurewebsites.net/Guidelines-Security/master/Guidelines-Security.html#CPS-mpd-scheme
from media.
works!
ty
from media.
I’m having the same issue. Is there a way to solve this problem? Adding manually the default_kid= string could be a workaround ?
from media.
Related Issues (20)
- OOM probably due to bad file
- Playback speed doesn't work on some devices with Audio Offload Enabled
- How to pass the tag in MediaItem to the customData of DataSpec?
- Android Auto Grid Layout with Media3 HOT 4
- Exoplayer.release did not free memory? Is it a Known issues??2.11.8 and 2.19.1
- Exoplayer does not resume once the Ad creative load is blocked via Charles HOT 3
- "Session ID must be unique. ID=" when building a session HOT 4
- Rename setShowPlayButtonIfPlaybackIsSuppressed in MediaSession.Builder
- Media3 exo player controls position in a horizontal tab HOT 1
- Controlls position in a horizontal orientation with RESIZE_MODE_FILL HOT 4
- Add charles/fiddler... proxy block when playing hls media
- Player does not upscale LL Stream once it get to lowest resolution HOT 6
- Video is cut on the edge when using Compose and uses RESIZE_MODE_ZOOM - Only Android 14 HOT 1
- [CMCD] Too many buffer starvation reports HOT 10
- Equalizer support
- ERROR_CODE_IO_UNSPECIFIED error on HLS stream HOT 11
- TTML subtitles - Opacity not compliant with TTML specification HOT 6
- [Transformer] Overlay rotation around the X and Y axles HOT 3
- How to set defaultPositionUs of a Window in the Timeline? HOT 2
- Non-Exoplayer TimeBar with Exoplayer Function
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from media.