Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drm Video not played:"The operation couldn’t be completed" #3417

Closed
Jianlong-Nie opened this issue Dec 11, 2023 · 13 comments
Closed

Drm Video not played:"The operation couldn’t be completed" #3417

Jianlong-Nie opened this issue Dec 11, 2023 · 13 comments
Labels
Platform: iOS triage needed Help needed to confirm the issue

Comments

@Jianlong-Nie
Copy link

Jianlong-Nie commented Dec 11, 2023

Platform

Which player are you experiencing the problem on:

  • iOS 17.1.2

Environment info

Library version: 6.0.0-beta.2
Device: iphone 12
IOS 17.1.2

System:
  OS: macOS 14.1.2
  CPU: (8) x64 Apple M1
  Memory: 21.60 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.9.0
    path: /usr/local/bin/node
  Yarn:
    version: 4.0.2
    path: /opt/homebrew/bin/yarn
  npm:
    version: 8.19.2
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2023.11.20.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.14.3
    path: /Users/jianlongnie/.rvm/gems/ruby-2.7.2/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - watchOS 10.0
  Android SDK:
    API Levels:
      - "28"
      - "29"
      - "30"
      - "31"
      - "32"
      - "33"
    Build Tools:
      - 28.0.3
      - 29.0.2
      - 29.0.3
      - 30.0.2
      - 30.0.3
      - 31.0.0
      - 32.0.0
      - 33.0.0
    System Images:
      - android-31 | Google TV ARM 64 v8a
      - android-31 | Google APIs ARM 64 v8a
      - android-33 | Google APIs Intel x86 Atom_64
      - android-33 | Google Play Intel x86 Atom_64
      - android-S | Google APIs ARM 64 v8a
      - android-UpsideDownCake-ext5 | Google APIs Intel x86_64 Atom
    Android NDK: 22.1.7171670
IDEs:
  Android Studio: 2022.2 AI-222.4459.24.2221.10121639
  Xcode:
    version: 15.0.1/15A507
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 11.0.15.1
    path: /Library/Java/JavaVirtualMachines/jdk-11.0.15.1.jdk/Contents/Home/bin/javac
  Ruby:
    version: 2.7.2
    path: /Users/jianlongnie/.rvm/rubies/ruby-2.7.2/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: true
  newArchEnabled: false

Steps To Reproduce

 <View style={{ height: itemHeight, width, backgroundColor: "red" }}>
          <StyledVideo
            className={classNames(
              "w-full",
              !loaded ? "hidden" : "block",
              className
            )}
            controls
            drm={{
              type: DRMType.FAIRPLAY,
              licenseServer: getLicenseUrl("fairplay"),
              certificateUrl: fairplayCertificateUrl,
              headers: {
                Authorization: `Bearer ${accessToken}`
              },
              getLicense: (spcString, contentId, licenseUrl) => {
                const myHeaders = new Headers()
                myHeaders.append(
                  "Content-Type",
                  "application/x-www-form-urlencoded"
                )
                myHeaders.append("Authorization", `Bearer ${accessToken}`)
                const raw = `spc=${spcString}&assetId=${contentId}`

                const requestOptions = {
                  method: "POST",
                  headers: myHeaders,
                  body: raw
                }

                return fetch(licenseUrl, requestOptions)
                  .then((response) => response.text())
                  .then((result) => {
                    alert(result)
                    return result
                  })
                  .catch((error) => console.log("error", error))
              }
            }}
            onEnd={() => {
              if (ref) {
                pause()
                setCurrentTime(duration)
              }
            }}
            onError={(error) => {
              console.log(error)
            }}
            onFullscreenPlayerDidDismiss={() => {
              setFullScreen(false)
            }}
            onFullscreenPlayerDidPresent={() => {
              setFullScreen(true)
            }}
            onLoad={({ duration, naturalSize }) => {
              alert("onload结束")
              setDuration(duration)
              handleVideoSize(naturalSize.width, naturalSize.height)
              setLoaded(true)
            }}
            onPlaybackRateChange={({ playbackRate }) => {
              if (playbackRate === 0) {
                pause()
              } else {
                play()
              }
            }}
            onProgress={({ currentTime }) => {
              setCurrentTime(currentTime)
            }}
            paused={!isPlaying}
            poster={poster}
            ref={ref}
            resizeMode={ResizeMode.CONTAIN}
            source={{
              uri: src
            }}
            style={{ height: itemHeight, width, backgroundColor: "red" }}
            volume={volume}
          />
        </View>

getLicense returned successfully,but i got error {"error": {"code": 1718449215, "domain": "CoreMediaErrorDomain", "localizedDescription": "The operation couldn’t be completed. (CoreMediaErrorDomain error 1718449215.)", "localizedFailureReason": "", "localizedRecoverySuggestion": ""}, "target": 28459}

video type is m3u8

@freeboub
Copy link
Collaborator

Is it the same issue than: #3406 ?
Was it working with 5.2 ?

@freeboub freeboub added Platform: iOS triage needed Help needed to confirm the issue labels Dec 11, 2023
@Jianlong-Nie
Copy link
Author

The operation couldn’t be completed

Is it the same issue than: #3406 ? Was it working with 5.2 ?

i dont think it is same issue,i got this error info {"error": {"code": -19152, "domain": "CoreMediaErrorDomain", "localizedDescription": "The operation couldn’t be completed. (CoreMediaErrorDomain error -19152 - The operation couldn’t be completed. (CoreMediaErrorDomain error -19152.))", "localizedFailureReason": "", "localizedRecoverySuggestion": ""}, "target": 1309},does the error code 19152 mean something? @freeboub

@hzw0407
Copy link

hzw0407 commented Dec 19, 2023

The operation couldn’t be completed

Is it the same issue than: #3406 ? Was it working with 5.2 ?

i dont think it is same issue,i got this error info {"error": {"code": -19152, "domain": "CoreMediaErrorDomain", "localizedDescription": "The operation couldn’t be completed. (CoreMediaErrorDomain error -19152 - The operation couldn’t be completed. (CoreMediaErrorDomain error -19152.))", "localizedFailureReason": "", "localizedRecoverySuggestion": ""}, "target": 1309},does the error code 19152 mean something? @freeboub

I also have the same problem. How should I solve it?

@Jianlong-Nie
Copy link
Author

@freeboub any update?

@dgocoder
Copy link

We're experiencing the same issue. For whatever reason 6.0.0-alpha.8 works no problem. Upgrading to beta introduces this issue

@facugu1998
Copy link
Contributor

Hello, we faced the same problem with some of our content. We found that the problem happens in the line 156 of RCTResourceLoaderDelegate:

 self._onGetLicense?(["licenseUrl": self._drm?.licenseServer ?? loadingRequest.request.url?.absoluteString ?? "",
                                     "contentId": contentId ?? "",
                                     "spcBase64": spcData.base64EncodedString(options: []),
                                     "target": self._reactTag])

When the onGetLicense function calls setLicenseResult, it passes the licenseServer url. So, it searches in the loadingRequests dictionary with that key:

//RCTResourceLoaderDelegate Line 71
guard let loadingRequest = _loadingRequests[licenseUrl] else {
    setLicenseResultError("Loading request for licenseUrl \(licenseUrl) not found", licenseUrl)
    return
}

But the real key is "loadingRequest.request.url?.absoluteString".

We managed to make it work by deleting self._drm?.licenseServer ??:

 self._onGetLicense?(["licenseUrl":  loadingRequest.request.url?.absoluteString ?? "",
                                     "contentId": contentId ?? "",
                                     "spcBase64": spcData.base64EncodedString(options: []),
                                     "target": self._reactTag])

or by not passing licenseServer in DRM config at react component level.

We introduced this bug on this PR: #3261

@freeboub
Copy link
Collaborator

freeboub commented Mar 1, 2024

I investigated this issue also this week and came to the same conclusion. I think we just need to apply this patch, I will open a pr for that !

@freeboub
Copy link
Collaborator

finally done here: #3578
can you please test if this PR fix your issue please ?

@facugu1998
Copy link
Contributor

Hello @freeboub, I tested the solution and to make it work I had to change Video.tsx from this:

if (data && data.spcBase64) {
    const getLicenseOverride = drm.getLicense(
      data.spcBase64,
      data.contentId,
      data.licenseUrl,
      data.loadedLicenseUrl,
    );
    const getLicensePromise = Promise.resolve(getLicenseOverride); // Handles both scenarios, getLicenseOverride being a promise and not.
    getLicensePromise
      .then((result) => {
        if (result !== undefined) {
          nativeRef.current &&
            VideoManager.setLicenseResult(
              result,
              data.licenseUrl,
              getReactTag(nativeRef),
            );
        } else {
          nativeRef.current &&
            VideoManager.setLicenseResultError(
              'Empty license result',
              data.licenseUrl,
              getReactTag(nativeRef),
            );
        }
      })
      .catch(() => {
        nativeRef.current &&
          VideoManager.setLicenseResultError(
            'fetch error',
            data.licenseUrl,
            getReactTag(nativeRef),
          );
      });
  } else {
    VideoManager.setLicenseResultError(
      'No spc received',
      data.licenseUrl,
      getReactTag(nativeRef),
    );
  }

to this:

if (data && data.spcBase64) {
    const getLicenseOverride = drm.getLicense(
      data.spcBase64,
      data.contentId,
      data.licenseUrl,
      data.loadedLicenseUrl,
    );
    const getLicensePromise = Promise.resolve(getLicenseOverride); // Handles both scenarios, getLicenseOverride being a promise and not.
    getLicensePromise
      .then((result) => {
        if (result !== undefined) {
          nativeRef.current &&
            VideoManager.setLicenseResult(
              result,
              data.loadedLicenseUrl,
              getReactTag(nativeRef),
            );
        } else {
          nativeRef.current &&
            VideoManager.setLicenseResultError(
              'Empty license result',
              data.loadedLicenseUrl,
              getReactTag(nativeRef),
            );
        }
      })
      .catch(() => {
        nativeRef.current &&
          VideoManager.setLicenseResultError(
            'fetch error',
            data.loadedLicenseUrl,
            getReactTag(nativeRef),
          );
      });
  } else {
    VideoManager.setLicenseResultError(
      'No spc received',
      data.loadedLicenseUrl,
      getReactTag(nativeRef),
    );
  }

Because it was still passing the licenseUrl as the key for searching in the loadingRequests dictionary.

@freeboub
Copy link
Collaborator

@facugu1998 Thank you for the quick feedback, I have updated the PR by changing licenseUrl to loadedLicenseUrl in setLicenseResultError and setLicenseResult calls.

@facugu1998
Copy link
Contributor

@freeboub Perfect! I tested it with our content, and it's working right.

@freeboub
Copy link
Collaborator

pull request merged to master, will be available in beta.6

@rahulnainwalttn
Copy link

@facugu1998 Could you please share the code snippet? I am also facing the same issue but not able to get a working solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: iOS triage needed Help needed to confirm the issue
Projects
None yet
Development

No branches or pull requests

6 participants