Giter Site home page Giter Site logo

Comments (4)

fr3ns1s avatar fr3ns1s commented on June 19, 2024 2

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.

oceanjules avatar oceanjules commented on June 19, 2024

@fr3ns1s,

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.

fr3ns1s avatar fr3ns1s commented on June 19, 2024

works!
ty

from media.

marksdemellin avatar marksdemellin commented on June 19, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.