代码之家  ›  专栏  ›  技术社区  ›  Billyjoker

Exoplayer2 DRM异常shouldWaitForKeys

  •  0
  • Billyjoker  · 技术社区  · 9 年前

        protected DrmSessionManager<FrameworkMediaCrypto> generateDrmSessionManager() {
            // DRM is only supported on API 18 + in the ExoPlayer
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
                return null;
            }
    
            // Widevine will capture the majority of use cases however playready is supported on all AndroidTV devices
            UUID uuid = C.WIDEVINE_UUID;
            final String licenseURL = "http://video.aaa";
    
            HttpMediaDrmCallback drmCallback =
                    new HttpMediaDrmCallback(
                            licenseURL, buildHttpDataSourceFactory(false), KEY_REQUEST_PROPERTIES);
    
            try {
                return new DefaultDrmSessionManager<>(
                        uuid, FrameworkMediaDrm.newInstance(uuid), drmCallback, null, mainHandler, capabilitiesListener);
            } catch (Exception e) {
                Log.d(TAG, "Unable to create a DrmSessionManager due to an exception", e);
                return null;
            }
        }
    

    我有drmSession,然后当HttpMediaDrmCallback执行时

    executePost(dataSourceFactory, url, request.getData(), requestProperties);
    

    里面有一个导致 onDrmSessionManagerError (java.lang.IllegalArgumentException)调用时:

    HttpDataSource dataSource = dataSourceFactory.createDataSource();
    

    在com.google.android.exoplayer2.mediacodec.mediacoderender.shouldWaitForKeys(mediacodecrender.java:735) 在com.google.android.exoplayer2.mediacodec.mediacoderender.feedInputBuffer(mediacodecrender.java:676) 位于com.google.android.exoplayer2.mediacodec.mediacederender.render(mediacodecrender.java:511) 在com.google.android.exoplayer2.exopplayerimplinternal.doSomeWork(exoplauerimplininternal.java:479) 在com.google.android.exoplayer2.exopplayerimplinternal.handleMessage(exoplayer-mplininternal.java:308) 在android.os.Handler.dispatchMessage(Handler.java:98) 运行(HandlerThread.java:61) 在com.google.android.exoplayer2.drm.DefaultDrmSessionManager.onError(defaultdrmsissionmanager.java:604) 在com.google.android.exoplayer2.drm.DefaultDrmSessionManager.onKeysError(DefaultDrmSessionManager.java:599) 在com.google.android.exoplayer2.drm.DefaultDrmSessionManager.access$900(DefaultDrmSessionManager.java:50) 在com.google.android.exoplayer2.drm.DefaultDrmSessionManager$postressehandler.handleMessage(defaultdrmsissionmanager.java:679) 运行(HandlerThread.java:61) 原因:java.lang.IllegalArgumentException 在com.google.android.exoplayer2.upstream.DefaultHttpDataSource.java:148 在com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory.createDataSourceInternal(defaultHttp数据源工厂.java:81) 在com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory.createDataSourceInternal(defaultHttp数据源工厂.java:22) 在com.google.android.exoplayer2.upstream.HttpDataSource$BaseFactory.createDataSource(HttpDataSource.java:176) 在com.google.android.exoplayer2.drm.HttpMediaDrmCallback.executeKeyRequest(httpmediadarmcallBack.java:134) 在android.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:135) 运行(HandlerThread.java:61)

    1 回复  |  直到 9 年前
        1
  •  1
  •   Mick    9 年前

    异常是由userAgent字符串在此处为null或长度为零引起的:

    public DefaultHttpDataSource(String userAgent, Predicate<String> contentTypePredicate,
          TransferListener<? super DefaultHttpDataSource> listener, int connectTimeoutMillis,
          int readTimeoutMillis, boolean allowCrossProtocolRedirects,
          RequestProperties defaultRequestProperties) {
        this.userAgent = Assertions.checkNotEmpty(userAgent);  <---- Exception is here
        this.contentTypePredicate = contentTypePredicate;
        this.listener = listener;
        this.requestProperties = new RequestProperties();
        this.connectTimeoutMillis = connectTimeoutMillis;
        this.readTimeoutMillis = readTimeoutMillis;
        this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
        this.defaultRequestProperties = defaultRequestProperties;
      }
    

    /**
       * Returns a user agent string based on the given application name and the library version.
       *
       * @param context A valid context of the calling application.
       * @param applicationName String that will be prefix'ed to the generated user agent.
       * @return A user agent string generated using the applicationName and the library version.
       */
      public static String getUserAgent(Context context, String applicationName) {
        String versionName;
        try {
          String packageName = context.getPackageName();
          PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
          versionName = info.versionName;
        } catch (NameNotFoundException e) {
          versionName = "?";
        }
        return applicationName + "/" + versionName + " (Linux;Android " + Build.VERSION.RELEASE
            + ") " + ExoPlayerLibraryInfo.VERSION_SLASHY;
      }
    

    您可以在演示应用程序中看到它的使用和设置示例: https://github.com/google/ExoPlayer/tree/release-v2/demo

    https://google.github.io/ExoPlayer/guide.html )其中包括显示正在设置的userAgent的示例:

    // Measures bandwidth during playback. Can be null if not required.
    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    // Produces DataSource instances through which media data is loaded.
    DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context,
        Util.getUserAgent(context, "yourApplicationName"), bandwidthMeter);
    // Produces Extractor instances for parsing the media data.
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
    // This is the MediaSource representing the media to be played.
    MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri,
        dataSourceFactory, extractorsFactory, null, null);
    // Prepare the player with the source.
    player.prepare(videoSource);