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

iOS DRM Fixes for License Fetching #2208

Merged
merged 11 commits into from
Jan 13, 2021

Conversation

nickfujita
Copy link
Collaborator

@nickfujita nickfujita commented Nov 13, 2020

Adds in fixes for using DRM on iOS while for both using getLicense and fetching the license in native code.

There are a couple fixes taken from https://github.com/react-native-video/react-native-video/pull/2128/files.

This expands on that work to update the formatting in the case where the user would like to not specify a function to fetch the license on their own using getLicense. Rather this should allow the native code to fetch the license for you.

In several of the comments on the original iOS DRM PR, it was mentioned that it only seemed to work with getLicense. But even then, there were still some changes that others required in order to get that working. Adds fixes that seem to be used by many from the original PR comment from @Hobahung

  • Cleans up contentID extraction and contentIdData encoding
  • Updates the onGetLicense arguments to only those used by others using this library
  • Fixed crash for onGetLicense when the certificate data was assumed to be base64 encoded, and incorrectly passed as spc data.
  • Updates spc data formatting in the license request performed on the native code side when onGetLicense is not present

@STIENLILLY @Hobahung
Would you mind testing this PR for iOS to make sure it's still working for your applications? I noticed that in the example in the original ios drm PR getLicense was being used, as I assumed that the code without it was not working. Would you mind trying without the getLicense method as well?

@danhodos @sunnyoui
Had to make a few updates described above in order to get the DRM license fetching and successful loading into the player working. These differ from the logic in the original PR that you had both created/validated. So I wanted to make sure to include you both in the discussion as well to make sure that this PR still provides a working DRM solution for you both on iOS

@nickfujita nickfujita changed the title updates to code to allow full native drm code to run iOS DRM Fixes for License Fetching Nov 13, 2020
@nickfujita
Copy link
Collaborator Author

@STIENLILLY @Hobahung @danhodos @sunnyoui

Just wanted to try pinging you all again to see if you were still using react-native-video in your projects; specifically DRM for iOS. If so, could you please test out the changes in this PR, as I would like to ensure that the changes still work with your projects.

If we don't hear back, will have to assume that you are no longer using RNV, and will look to merge the changes after a review from @cobarx

@nickfujita
Copy link
Collaborator Author

@cobarx Could you please review this PR when you get a chance, so that we may proceed to merge to master?

@0xleeaki
Copy link

0xleeaki commented Dec 2, 2020

Hi @nickfujita ,
I have just tested your function, it has an crash in ios when using drm video.
My config.

{
                    type: DrmPlayerComponentConfig.DRMType.FAIRPLAY,
                    certificateUrl: AppConfig.videoCertificateUrl,
                    headers: {
                      Authorization: drmMediaSource.headers.Authorization,
                      'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    getLicense: (
                      spc: string | Blob,
                      contentId: any,
                      licenseUrl: string,
                    ) => {
                      const formData = new FormData();
                      formData.append('spc', spc);
                      return fetch(licenseUrl.replace('skd', 'https'), {
                        method: 'POST',
                        headers: {
                          Authorization:
                            drmMediaSource.headers?.Authorization || '',
                          'Content-Type': 'application/x-www-form-urlencoded',
                        },
                        body: formData,
                      })
                        .then((response) => {
                          return new Promise((resolve, reject) => {
                            response.blob().then((blob) => {
                              new Response(blob).text().then((text) => {
                                resolve(
                                  text
                                    .replace('<ckc>', '')
                                    .replace('</ckc>', ''),
                                );
                              });
                            });
                          });
                        })
                        .catch((error) => {
                          setErrorMessage(error.toString());
                        });
                    },
                  }

image

@nickfujita
Copy link
Collaborator Author

@Hobahung thanks for testing. When using a provided getLicense method, the main differences appear to be the way contentId and contentIdData values are derived. I took them from this PR, and they appear to be working for me.

For my project I'm not using getLicense, so updated to code to have separate handing logic when using getLicense or not, and have changed the way the contentIdData value is initialized to the same way that you had it in your comment on the original PR. Could you please try testing again and seeing if that works? If not, could you also please try manually updating contentId to what it was originally, and see if that works for you instead? NSString *contentId = url.host;

Also I'm not very versed in Objective-c, so would be open to any recommendations of formatting this better, as there is much duplicate code in this approach.

@nickfujita
Copy link
Collaborator Author

Hi @Hobahung wanted to ping you again to see if you could please try this out again. I'd like to get this resolved and merged by the end of the week if possible.

@KrzysztofGastolek
Copy link

KrzysztofGastolek commented Dec 15, 2020

Hi @Hobahung wanted to ping you again to see if you could please try this out again. I'd like to get this resolved and merged by the end of the week if possible.

Hi, I've tried your solution, but it doesn't work. Still got error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:
(0x193512878 0x1a7a68c50 0x193582e1c 0x19358f270 0x193403550 0x1933f5dd0 0x1057955a8 0x19310524c 0x193106db0 0x193117a68 0x193118120 0x1dbc087c8 0x1dbc0f75c)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]'
terminating with uncaught exception of type NSException

I've also tried to change contentId. No luck.

@nickfujita
Copy link
Collaborator Author

Thanks @KrzysztofGastolek for testing. I spent some time debugging, and found that the reason for this crash appears to be that in the example from input from @Hobahung, the licenseServer field is not being passed. This is required, since the the adjustments suggested by @Hobahung request that the licenseServer be passed back to getLicense as licenseUrl: string,. However if the field is not passed, a crash occurs. I've since added a catch to default the license URL to and empty string, if it is not passed in the initial config. Please pass an input value for licenseServer if you expect the getLicense to return an argument for licenseUrl in your example above.

While debugging, I've also gone ahead and cleaned up the code to better preserve the original code between getting the license via JS or native. And also went ahead and reverted the changes from this PR, since it seems that it was not in the original comment from @Hobahung in the PR for the original ios drm support.

@Hobahung in your comment on the original drm PR, you reference the licenseUrl variable, but I am not finding this specific variable name in the existing code. So I'm assuming that it's coming from the input config field licenseServer. Could you please confirm that was your intention, or were you pulling licenseUrl from somewhere else? Also if it's being passed as an input config argument, only to be referenced again in JS, can we just omit this from the arguments for the getLicense callback since the js code should already have this value?

@nickfujita
Copy link
Collaborator Author

@Hobahung & @KrzysztofGastolek Hope you both had a relaxing and safe new year! Was wondering if either of you would possibly have a few min to have a look at my last comment. The reason for the error seems to be that the licenseServer field was left blank in the input config, which is why it was crashing.

@KrzysztofGastolek
Copy link

@Hobahung & @KrzysztofGastolek Hope you both had a relaxing and safe new year! Was wondering if either of you would possibly have a few min to have a look at my last comment. The reason for the error seems to be that the licenseServer field was left blank in the input config, which is why it was crashing.

Hello. I hope you had a good one as well!

About the crashing issue, I've actually used @Hobahung solution (with licenseUrl change made by myself) and it works ok. I will try to check your solution today or tommorow and get back with results.

@KrzysztofGastolek
Copy link

KrzysztofGastolek commented Jan 6, 2021

@nickfujita

OK, so I've replaced my current react-native-video (working) with your version and my app is not crashing anymore, but still not working with DRM. Function getLicense is never invoked. After a while I am getting timeout error:

error: code: -16833 domain: "CoreMediaErrorDomain" localizedDescription: "The operation couldn’t be completed. (CoreMediaErrorDomain error -16833 - Nie można ukończyć tej operacji. (Błąd CoreMediaErrorDomain -16833 - crypt key received slowly))" localizedFailureReason: "" localizedRecoverySuggestion: "" target: 99

There are no errors in xcode.

@nickfujita
Copy link
Collaborator Author

nickfujita commented Jan 6, 2021

@KrzysztofGastolek Thanks for testing. Could you please confirm whether or not you are passing an input value for the licenseServer field, and possibly a sample of what your input config looks like?

In your implementation, from where was the licenseUrl argument in the getLicense callback function being sourced if not provided via the input config parameter licenseServer

@KrzysztofGastolek
Copy link

@KrzysztofGastolek Thanks for testing. Could you please confirm whether or not you are passing an input value for the licenseServer field, and possibly a sample of what your input config looks like?

In your implementation, from where was the licenseUrl argument in the getLicense callback function being sourced if not provided via the input config parameter licenseServer

OK, so here is my drm object passed to video component (I've removed specific data):

certificateUrl: "https://fp-keyos.licensekeyserver.com/cert/[certId].der" getLicense: ƒ (spc, contentId, licenseUrl) headers: customdata: "mycustomdata" licenseServer: "https://fp-keyos.licensekeyserver.com/getkey" type: "fairplay"

As you can see, I am passing licenseServer, but that is not a problem. The issue is that video component never invokes getLicense function. In the function I am expecting licenseUrl all the times, but still, if the function is not invoked, it doesn't matter :) My app is a rough prototype, because I am actually working with react-native for the first time and have very limited knowlege about native code, but I will try to debug this module to provide more information. If you have any hints how to debug this, feel free to contact me. IOS DRM playback with custom getLicense is crucial to my app and I care about this fix a lot :)

@KrzysztofGastolek
Copy link

KrzysztofGastolek commented Jan 6, 2021

I think I've found the problem. In Video.js function _onGetLicense it is expecting data.spc value but it gets:

contentId: "..."
licenseUrl: "https://fp-keyos.licensekeyserver.com/getkey"
spcBase64: "..."

EDIT:

I've changed data.spc to data.spcBase64 and it works :D

@nickfujita
Copy link
Collaborator Author

nickfujita commented Jan 7, 2021

@KrzysztofGastolek Thanks for finding that. Def. and oversight on my part (sorry about that). I confirmed the fix on my end as well.

Would you mind giving it a once over again with the latest commit, and provide your approval on this PR if possible (comment approval is also fine).

@nickfujita
Copy link
Collaborator Author

@leolaki would you also mind testing with the latest fix?

@KrzysztofGastolek
Copy link

@KrzysztofGastolek Thanks for finding that. Def. and oversight on my part (sorry about that). I confirmed the fix on my end as well.

Would you mind giving it a once over again with the latest commit, and provide your approval on this PR if possible (comment approval is also fine).

I've checked new commit both on iOS and Android builds, and it works ok. I am using custom getLicense function and specific licenseServer url.

@klauszhang
Copy link

Greetings @nickfujita,

I've checked your latest code with my setup, but I cannot get getLicense called for some reason. So HLS playback always fails (I assume there was no DRM call to license server).

I managed to get android DASH + Widevine working, but no luck with iOS DRM. I can get HLS content playing when there are no DRM.

I also tried the DRM information on safari browser it works fine so I assume the certificate the server works fine. I'm pretty new to RN so could have made some silly mistake here.

Here are my settings:

      <Video
        style={{...}}
        controls={true}
        source={{
          uri: source.src,
          type: 'm3u8',
        }}
        drm={{
          type: DRMType.FAIRPLAY,
          certificateUrl: drm.certificate_url,
          licenseServer: drm.key_request_url,
          base64Certificate: false,
          getLicense: spcString => {
            console.log('spcString', spcString)  // <- this never logs out

            // I copied some of the code from samples. But the function not called so I assume they doesn't matter anyway
            const base64spc = Base64.encode(spcString)
            const formData = new FormData()
            formData.append('spc', base64spc)
            return fetch(
              source.key_systems['com.apple.fps.1_0'].key_request_url,
              {
                method: 'POST',
                headers: {},
                body: formData,
              }
            )
              .then(response => response.text())
              .then(response => {
                return response
              })
              .catch(error => {
                console.error('Error', error)
              })
          },
        }}
      />

@KrzysztofGastolek
Copy link

@klauszhang

Maybe try to remove base64Certificate key from drm prop. It works without it in my app. Also add handler for onError prop to catch errors.

function onError(e) {
  console.log('Error', e);
}

<Video
    ...
    onError={onError}
/>

@klauszhang
Copy link

@KrzysztofGastolek Thanks for the hint, I tried to remove base64Certificate and it doesn't seem working.

Can you confirm your sample works with DRM enabled content? As if I use apple sample HLS sample (http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8) it works fine but not working with DRM enabled.

I also tried to add onError log and it does log anything..

@KrzysztofGastolek
Copy link

@klauszhang

Yes, newest commit works fine with both FAIRPLAY (iOS with custom getLicense) and WIDEVINE (android).

@klauszhang
Copy link

klauszhang commented Jan 11, 2021

Thank you for confirming @KrzysztofGastolek .

I tried a few times but still cannot get it working. I noticed the code stopped at

dispatch_queue_t queue = dispatch_queue_create("assetQueue", nil);

and afterwards resourceLoader never get run.

I am not even rookie of objective-c so I cannot debug what's going on here? I attached xcode debugger and there's no error is thrown. seems to me after the queue dispatched there's nothing happen.

@KrzysztofGastolek
Copy link

Thank you for confirming @KrzysztofGastolek .

I tried a few times but still cannot get it working. I noticed the code stopped at

dispatch_queue_t queue = dispatch_queue_create("assetQueue", nil);

and afterwards resourceLoader never get run.

I am not even rookie of objective-c so I cannot debug what's going on here? I attached xcode debugger and there's no error is thrown. seems to me after the queue dispatched there's nothing happen.

Are you sure you are passing correct source? I don't know excactly how player works, but maybe it stops before it even tries to obtain DRM data? I don't think m3u8 is correct type for a source.

@klauszhang
Copy link

I believe it is, m3u8 is HLS streaming format and I can get none DRM playback successful. If you want I can DM you the source and have a try. FYI @nickfujita as well. I guess there's something wrong with m3u8 type with fairplay?

@KrzysztofGastolek
Copy link

KrzysztofGastolek commented Jan 12, 2021

@klauszhang

I think type is for mime., m3u8 is playlist type, not mime. For HLS the correct mime is application/vnd.apple.mpegurl, but I had no problems with playback without specifying type. I can check your source with my app if you want.

@nickfujita
Copy link
Collaborator Author

nickfujita commented Jan 12, 2021

@klauszhang
While testing, I'm also using m3u8, so should not be an issue. Could you possibly try a couple things:

  • Without, base64Certificate parameter
  • Make sure on latest commit for PR branch (44b5915). There was a fix made on the 7th that prevented getLicense from being triggered

@nickfujita
Copy link
Collaborator Author

Also, @klauszhang, could you please confirm you are testing iOS drm on a physical device, and not the simulator?

@klauszhang
Copy link

Thank you for your reply. I added you both to the sample repository. the sample is in https://github.com/klauszhang/drm-poc/blob/master/sample.js

@klauszhang
Copy link

@nickfujita sorry I was trying that on the simulator, I will try on a physical device really quick to see if it works

@klauszhang
Copy link

klauszhang commented Jan 12, 2021

got slightly different log if run on physical device. But it crashes when run.

2021-01-12 23:05:47.646581+1300 drmpoc[870:930669] -[NSURL length]: unrecognized selector sent to instance 0x281f620d0
2021-01-12 23:05:47.647076+1300 drmpoc[870:930669] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL length]: unrecognized selector sent to instance 0x281f620d0'
*** First throw call stack:
(0x23301998c 0x2321f29f8 0x232f361c8 0x23301f1d4 0x233020e6c 0x232fc672c 0x232fc9dc8 0x10438ad5c 0x1046768ac 0x1046765ac 0x233021010 0x232f02be0 0x2390c8168 0x2390c7ea4 0x105ad36f4 0x105ad4c78 0x105adcbf4 0x105add8b4 0x105ae777c 0x232c39114 0x232c3bcd4)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSURL length]: unrecognized selector sent to instance 0x281f620d0'
terminating with uncaught exception of type NSException
(lldb) 

@nickfujita
Copy link
Collaborator Author

@klauszhang Took a look at the sample project, and it appears that it is using the latest release version of react-native-video, and not the branch for this PR. While testing the changes for this PR, please utilize the PR branch or else the changes being tested will not be present.

"react-native-video": "git+ssh://git@github.com/nickfujita/react-native-video.git#44b5915f671589caea0df71924b6cffc1858d10b",

I updated the dependency locally, and found that the getLicense method is being triggered as expected. Could you please confirm.

@klauszhang
Copy link

@nickfujita Thank you very much for your help, I was copying the code and replace it in node_modules and expecting it would apply the change but it seems not.

It is working like a charm now and you're right it only plays on the physical device rather than on simulator.

@EyMaddis
Copy link

Related as it breaks some DRM providers: #2305

@mezalejandro
Copy link

Hello, I am testing DRM and it is not working for me on iOS, can someone help me?

@KrzysztofGastolek
Copy link

Hello, I am testing DRM and it is not working for me on iOS, can someone help me?

Sure.

@mezalejandro
Copy link

Hello @KrzysztofGastolek , I am testing with an iphone simulator and it does not work but now testing on a physical device I get this message
Screen Shot 2021-07-14 at 17 16 37

<Video
            source = {{
              uri: 'https://xxx.cloudfront.net/out/v1/xxxx/index.m3u8',
          }}
          drm = {{
              type: DRMType.FAIRPLAY,
              licenseServer: 'https://fps.ezdrm.com/api/licenses/XXXX-XXXX-XXX-XX',
              certificateUrl: 'https://xxx.cloudfront.net/live/players/test/1.0/fairplay.cer'
          }} 
          onError={(err) => console.log('error ', err)}
          style={styles.backgroundVideo} />

@mezalejandro
Copy link

in getLicense how do I pass the base64?
In this way?

getLicense: (spcString) => {
                const base64spc = Base64.encode(`${contentId}+${certificateUrl}`)

@samueleastdev
Copy link

@mezalejandro I am getting the exact same error as you did you manage to resolve this issue?

@cihanbas
Copy link

in getLicense how do I pass the base64? In this way?

getLicense: (spcString) => {
                const base64spc = Base64.encode(`${contentId}+${certificateUrl}`)

Hi @mezalejandro how do you solve this issue? i'm getting same issue

@mezalejandro
Copy link

Hello @cihanbas in my case contentId I had those data, so that it works.
The contentId was passed to me.

MeenuDhanoa added a commit to railroadmedia/react-native-video that referenced this pull request Aug 13, 2024
* Fix so background audio from other apps can play when disableFocus is true. requestAudioFocus was being run regardless of there being a src, so I made it so that only gets requested when a src exists.

* Added details to readme and changelog

* update for androidX

* change minSdkVersion back to 16

* update readme

* remove duplicate ReactVideoPackage()

* add readme to migrating to AndroidX

* add read me

* fix read me

* pre androidX, upgrade to 28

* remove duplicated line in example

* change dead code in  example

* Remove calls to [super observe] to fix crash

* Add TheWidlarzGroup#1646 to changelog

* bring back super KVO with selector check

* Fix memory leak when using AVPlayerViewController, make sure to release player

* Updated changelog

* changelog for TheWidlarzGroup#1629

* bump version

* chang maven to google

* fix when controls & muted

* update changelog

* handle racing conditions when props are setted on exoplayer

* fix for setControls

* fix repeat

* comment why postDelayed

* remove extra whitespace

* remove rnpm

* 4.4.4

* Update README.md

Make installation parts easier to link

* Update README.md

fix typo

* Update README.md

Make more obvious the changes needed via using diff

* Update MainApplication.java

fix indent

* remove matchingfallbacks in example

* prepare 5.0.0 version

* cpck androidx

* change minSdkVersion back to 16

(cherry picked from commit a96fa33)

* update readme

(cherry picked from commit 3ddcba3)

* add readme to migrating to AndroidX

(cherry picked from commit 976ebcc)

* cpck readme

* fix read me

(cherry picked from commit ed25b3f)

* chang maven to google

(cherry picked from commit 8a8f215)

* cpck

* ad platform installation to TOC

(cherry picked from commit b0737bd)

* More update info

(cherry picked from commit 2f23cc0)

* 5.0.1

* Fixed Exoplayer doesn't work with mute=true TheWidlarzGroup#1696

* Updated README.md to include instructions for React Native 0.60 and above

* Removing the call to observeValueForKeyPath:ofObject:change:context: on super from RCTVideo.
If the super class is not actually observing the key, the app will crash. Checking to see if
the super class responds to this selector doesn't solve this issue.

react-native-video github issue: TheWidlarzGroup#1515

Discussion about this particular problem: https://stackoverflow.com/questions/6574714/whats-wrong-with-this-observevalueforkeypathofobjectchangecontext-implement

* Updated CHANGELOG to reflect bug fix in PR 1720

* added support for automaticallyWaitsToMinimizeStalling property on iOS

* update readme

* fix invert boolean property

* bumped version & updated changelog

* fix formatting issues

* fix formatting
fix crash iOS9

* changelog for TheWidlarzGroup#1696

* Update issue templates

* Update bug_report.md

* Update bug_report.md

* Fix indent and respect previous rate

* Bring the basic example back to a runnable state

* Remove Exoplayer deprecations

- Bump Exoplayer to 2.10.4
- Remove deprecated usages of Exoplayer methdos
- Add `ReactExoplayerConfig` as extension points to configure the Exoplayer instance

* Update changelog with Exoplayer update (TheWidlarzGroup#1766)

* update package json version

* update changelog version

* Add disableFocus to TOC

* fix typo in README

* Clear progress messages on STATE_IDLE and STATE_BUFFERING (TheWidlarzGroup#1768)

The progress message handler will duplicate recursions of the `onProgressMessage` handler on change of player state from any state to STATE_READY with `playWhenReady` is true (when video is not paused). This clears the messages on STATE_IDLE and STATE_BUFFERING to break the recursion.

* fix README about reportBandwidth (TheWidlarzGroup#1816)

* Fixes a situation when exiting fullscreen, where observed keypath values have not been released

* add try catch block around removal of observer keypaths on playerViewController

* Audio Poster issue fix (TheWidlarzGroup#1779)

* Add full screen support to Android Exoplayer (TheWidlarzGroup#1730)

* Bump version to 5.1.0-alpha

* Fix readme grammar (TheWidlarzGroup#1888)

* Improve Android Audio Focus (TheWidlarzGroup#1897)

Implement audio focus as per android docs:
https://developer.android.com/guide/topics/media-apps/audio-focus
https://medium.com/androiddevelopers/audio-focus-3-cdc09da9c122

AUDIOFOCUS_LOSS should abandon focus and not try resuming audio, this is done with AUDIOFOCUS_LOSS_TRANSIENT

This fixes at least:
- Audio not being paused after focus being taken by some voip applications
- Content resuming and pausing instantly sporadically (some race condition perhaps) when activity was resumed from background.

* Update changelog (TheWidlarzGroup#1913)

* docs(video): fix bufferConfig property name (TheWidlarzGroup#1855)

* Fix play/pause regression after added fullscreen support. (TheWidlarzGroup#1916)

* v5.1.0-alpha4

* Bump javascript dependencies (TheWidlarzGroup#1914)

Also update linting rules to match other community repositories.

* Add support for react-native Windows Cpp/WinRT (TheWidlarzGroup#1893)

This also deprecates the old react-native windows implementation

* Fix the `ref` sample code to remove the syntax error

* Update changelog

* v5.1.0-alpha5

* Don't set reactViewController view frame to whole screen (TheWidlarzGroup#1931)

this fixes the case on any time you have a react view that displays the video, but it's being rendered with controls but not as a full screen (ie. easily reproducible when you have a tabbar for instance - the reactViewController.view frame shouldnt be the whole screen bounds).

* Update onLoad event to include videoTracks info

* add mixWithOthers prop

* Update README.md

* Update index.ios.js

* Fix video dimensions for HLS streams

* Changelog

* Compare CGFloats instead

* Update CHANGELOG.md

* Update CHANGELOG, alpha-6 hasn't been released yet

* Implement pending seek

* Recommend npx pod-install for setup instructions

# Summary

We've been recommending devs use `npx pod-install` since it will attempt to install CocoaPods CLI if it's not available on the computer (cite [React Navigation setup guide](https://reactnavigation.org/docs/getting-started/#installing-dependencies-into-a-bare-react-native-project)). This has proved very useful for Expo users who are now migrating to the bare workflow and want to use community packages in their projects.

## Checklist

- [x] I have tested this on a device and a simulator
- [x] I added the documentation in `README.md`

* Expose currentPlaybackTime when live stream video (TheWidlarzGroup#1944)

* added trackId to exoplayer onLoad callback

* added trackInfo to bandwidth callback

* syntax fix

* syntax fix

* version update

* sending complete logcat for media playback exception ExoPlaybackException

* version bump

* package publish changes

* Live playback fix

* Version bump

* import fix

* version bump

* configurable preferredForwardBufferDuration

* configurable preferredForwardBufferDuration

* version update

* Exposing time

* exo player window current tsp

* return type

* Current window timestamp in epoch

* iOS changes

* version update

* Updated package.json

* updated version

* CurrentTime bug fix

* Updated package.json

* Updated currentPlaybackTime

* Updated currentPlayback logic

* Updated package.json

* Bug fix

* Added semicolon

* updated package.json

* Updated ReactVideoView

* updated verison

* Revert package.json changes

* Update ReactVideoView.java

* Use standard log

* Document preferredForwardBufferDuration (iOS)

* Document currentPlaybackTime

* Document trackId

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update README.md

* Update CHANGELOG.md

Co-authored-by: anubansal <anu.bansal@curefit.com>
Co-authored-by: Sivakumar J <sivakumar@curefit.com>
Co-authored-by: parikshit <parikshit@curefit.com>
Co-authored-by: anubansal92 <40559524+anubansal92@users.noreply.github.com>
Co-authored-by: Rishu Agrawal <rishu.agrawal@v.curefit.com>
Co-authored-by: rishu-curefit <54575330+rishu-curefit@users.noreply.github.com>

* [ios] Adaptive fullscreen in landscape by device orientation (TheWidlarzGroup#1862)

* update UIInterfaceOrientation in fullscreen

* update code

* Revert "[ios] Adaptive fullscreen in landscape by device orientation (TheWidlarzGroup#1862)" (TheWidlarzGroup#2043)

This reverts commit c9096d1.

* Upgrade exoplayer to 2.11.4 (TheWidlarzGroup#2034)

* Removed JS fullscreening for Android (TheWidlarzGroup#2013)

* Always set headers for iOS (TheWidlarzGroup#2014)

* Support preventsDisplaySleepDuringVideoPlayback (TheWidlarzGroup#2019)

* Add flag on iOS

* Add flag in Android

* Add documentation

* Add changelog entry

* Also set setKeepScreenOn

* Fix prop not being set

* add preventsDisplaySleepDuringVideoPlayback to exoplayer

* Update android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java

* Update android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java

Co-authored-by: Jens Andersson <jens@fritan.com>

Co-authored-by: Anton Tanderup <antontandrup@gmail.com>
Co-authored-by: Jens Andersson <jens@fritan.com>

* Fix exoplayer aspect ratio update on source changes (TheWidlarzGroup#2053)

* Fix exoplayer aspect ratio update on source changes

* Update CHANGELOG.md

* Add iOS and Android basic DRM support (TheWidlarzGroup#1445)

This PR adds support for DRM streams on iOS (Fairplay) and Android (Playready, Widevine, Clearkey)

I am neither Android nor iOS developer, so feel free to provide feedback to improve this PR.

**Test stream for ANDROID:**
```
testStream = {
        uri: 'http://profficialsite.origin.mediaservices.windows.net/c51358ea-9a5e-4322-8951-897d640fdfd7/tearsofsteel_4k.ism/manifest(format=mpd-time-csf)',
        type: 'mpd',
        drm: {
            type: DRMType.PLAYREADY,
            licenseServer: 'http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(persist:false,sl:150)'
        }
    };
```

or 
```
{
    uri: 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p.mpd',
    drm: {
        type: 'widevine', //or DRMType.WIDEVINE
        licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense',
        headers: {
            'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImZpcnN0X3BsYXlfZXhwaXJhdGlvbiI6NjAsInBsYXlyZWFkeSI6eyJyZWFsX3RpbWVfZXhwaXJhdGlvbiI6dHJ1ZX0sImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.FAbIiPxX8BHi9RwfzD7Yn-wugU19ghrkBFKsaCPrZmU'
        },
    }
}
```

**Test stream for iOS:**
Sorry but I can not provide free streams to test. If anyone can provide test streams, or found some we can use, please let me know to also test them.

It has been tested with a private provider and they work, at least with the `getLicense` override method. (An example implementation is provided in the README)

* Ready 5.1.0-alpha6 for release

* Prepare 5.1.0-alpha7

* Port over fix from 4.x branch

* Prepare 5.1.0-alpha8

* Bugfix: TheWidlarzGroup#1930

* Add ARM64 support for windows (TheWidlarzGroup#2137)

Adding arm64 support for RNW builds.

Nothing in this project is using anything that isn't already supported in arm64 windows libs. It was simply overlooked when RNW was originally added.

We have been using RNW and RNV in our project for 6+ months and just been using a patch-package to apply this change. Figured it was overdue to upstream this change.

You can see this similar code in the RNW repo.
https://github.com/microsoft/react-native-windows/blob/95935e008621778dbcec01363602c19abc060632/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleLibraryCPP.vcxproj#L28
and
https://github.com/microsoft/react-native-windows/blob/master/packages/microsoft-reactnative-sampleapps/windows/SampleLibraryCPP/SampleLibraryCPP.vcxproj#L44

* Update README.md (TheWidlarzGroup#2076)

You only need to perform linking for React Native < 0.60

* fix: Xcode 12 compatibility (TheWidlarzGroup#2152)

Latest Xcode 12 fails to build while without a module to depend on React-Core directly hence this change is necessary for native modules on iOS. This change requires to React Native 0.60.2 or newer. For more details please check: facebook/react-native#29633 (comment)

* Renaming Boolean etc to AsBoolean (TheWidlarzGroup#2119)

* Resolved an issue where setting a video to paused would ignore the “silent switch” setting

* iOS DRM Fixes for License Fetching (TheWidlarzGroup#2208)

* Update package.json version number to 5.1.1

* Update ReactNativeVideoCPP.vcxproj (TheWidlarzGroup#2288)

* Exoplayer: Use okhttp version specified in gradle.properties (TheWidlarzGroup#2340)

Because React Native uses okhttp, including exoplayer causes apps to use two different versions of okhttp.  This results in some unpredictable behavior.  Clients of `react-native-video` should be able to specify the same OKHTTP version to react-native and react-native video.

See where it's specified in react-native trunk: 
- https://github.com/facebook/react-native/blob/master/ReactAndroid/gradle.properties#L15
- https://github.com/facebook/react-native/blob/e1b6cd3f756aa034b11af6bf9960efb42bde8692/ReactAndroid/build.gradle#L452-L453

* React Native Windows updates (TheWidlarzGroup#2206)

Various updates for React Native Windows

**Docs**
* Fixed windows installation in readme
* Added local dev setup instructions

**Build**
* Added VS solutions for RNW 0.61, 0.62, and 0.63+
* Added clang-formatting definition

**Features**
* Fixed autolinking for RNW 0.63+
* Added support for `rate` property

**Examples**
* Upgraded examples/basic to RN 0.61 and replaced broken windows app

* Update README.md (TheWidlarzGroup#2292)

Fix broken link for ignoresilentswitch

* Fix AudoFocus pausing video when attempting to play (TheWidlarzGroup#2311)

Fix AudioFocus bug that could cause the player to stop responding to play/pause in some instances.

Fixes issue TheWidlarzGroup#1945

This was caused by the player requesting audio focus on each play (un-pause) and that resulted in a small window of Audio focus loss and then gain. The focus loss results in the player being paused while the player was supposed to play at the time. The solution is to keep track of Audio focus and not request new focus if we already have it.

* Upgrade ExoPlayer to 2.13.2 (TheWidlarzGroup#2317)

Upgrade ExoPlayer from 2.11.4 to 2.13.2 and fix any issues related to the upgrade and deprecated method use.

* update exoplayer to allow pre-init and content clear

* Fix for tvOS native audio menu language selector

* Release 5.2.0-alpha1

* Typo

* Release 5.2.0

* Use prop types from `deprecated-react-native-prop-types`

Starting with React Native 0.68, using Prop Types from `react-native` emits a warning.

* Update Video.js

Co-authored-by: Elliott Kember <elliott.kember@gmail.com>
# Conflicts:
#	Video.js

* Replace Image.propTypes with ImagePropTypes.
# Conflicts:
#	Video.js

* fix(Exoplayer): fix exoplayer version tà 2.13.3

* chore: fix build without exoplayer

* v5.2.1

* docs: update Android installation

* * removed duplicate method

* * fix onRemotePlayPause in android

* * remove duplicate code

* * fix cannot find symbol after RN update

---------

Co-authored-by: Kurt Johnson <kurt.johnson@lightmaker.com>
Co-authored-by: Kurt Johnson <kurtjohnson8@gmail.com>
Co-authored-by: vok <admin@MacOnes-MacBook-Pro-2.local>
Co-authored-by: Zaid Daghestani <zaid.daghestani@gmail.com>
Co-authored-by: Jens Andersson <jens@fritan.com>
Co-authored-by: Daniel Mariño Ruiz <1237997+CHaNGeTe@users.noreply.github.com>
Co-authored-by: Daniel Mariño <daniel.marino@24imedia.com>
Co-authored-by: Ash Mishra <a.mishra@nfb.ca>
Co-authored-by: Andrew Chae <asjchae@gmail.com>
Co-authored-by: Jamie Halvorson <jamie@halvorson.co.uk>
Co-authored-by: Nahuel Marisi <nahuel.marisi@klarna.com>
Co-authored-by: Jovan Stanimirovic <jovan@netlog.com>
Co-authored-by: Benoit Dion <unknown>
Co-authored-by: Benoit Dion <573574+benoitdion@users.noreply.github.com>
Co-authored-by: Bader Serhan <baderserhan@gmail.com>
Co-authored-by: Tsukasa Setoguchi <tsukasa.setoguchi@gmail.com>
Co-authored-by: Learnyst <shankar@karaokegarage.com>
Co-authored-by: IbrahimSulai <33604125+IbrahimSulai@users.noreply.github.com>
Co-authored-by: Benoit Dion <benoit@eliteness.app>
Co-authored-by: Mohammed Salman <msal4@outlook.com>
Co-authored-by: Michael Tintiuc <michaeltintiuc@users.noreply.github.com>
Co-authored-by: Piotr Błażejewicz (Peter Blazejewicz) <peterblazejewicz@users.noreply.github.com>
Co-authored-by: Benoit Dion <benoitdion@gmail.com>
Co-authored-by: Di Da <dida@microsoft.com>
Co-authored-by: Brandon Faulkner <college.bfaulk96@yahoo.com>
Co-authored-by: Marlon Andrade <marlonmandrade@gmail.com>
Co-authored-by: Hampton Maxwell <me@hamptonmaxwell.com>
Co-authored-by: Harrison Mendonça <harrisonmendonca@gmail.com>
Co-authored-by: Evan Bacon <baconbrix@gmail.com>
Co-authored-by: Param Aggarwal <paramaggarwal@gmail.com>
Co-authored-by: anubansal <anu.bansal@curefit.com>
Co-authored-by: Sivakumar J <sivakumar@curefit.com>
Co-authored-by: parikshit <parikshit@curefit.com>
Co-authored-by: anubansal92 <40559524+anubansal92@users.noreply.github.com>
Co-authored-by: Rishu Agrawal <rishu.agrawal@v.curefit.com>
Co-authored-by: rishu-curefit <54575330+rishu-curefit@users.noreply.github.com>
Co-authored-by: Tuan Luong <tuanluong.it@gmail.com>
Co-authored-by: limaAniceto <lima.aniceto@gmail.com>
Co-authored-by: Anders Lemke <mail@anderslemke.dk>
Co-authored-by: Anton Tanderup <antontandrup@gmail.com>
Co-authored-by: Jeferson Daniel <contato@jefersondaniel.com>
Co-authored-by: Daniel Mariño <35027703+danielmarino24i@users.noreply.github.com>
Co-authored-by: Hampton Maxwell <hmaxwell@ellation.com>
Co-authored-by: Nick Fujita <nickfujita@gmail.com>
Co-authored-by: redspear <willkoia@gmail.com>
Co-authored-by: Adam Gorman <namrog84@users.noreply.github.com>
Co-authored-by: Irwin <irwinwilliams@users.noreply.github.com>
Co-authored-by: Radek Czemerys <7029942+radko93@users.noreply.github.com>
Co-authored-by: Tero Paananen <54746036+tero-paananen@users.noreply.github.com>
Co-authored-by: Cameron Perry <cameron.perry@valtech.com>
Co-authored-by: Alexander Sklar <asklar@microsoft.com>
Co-authored-by: Sean Holbert <sdholbs@gmail.com>
Co-authored-by: Jon Thysell <thysell@gmail.com>
Co-authored-by: Milan Susnjar <milanrs@gmail.com>
Co-authored-by: Armands Malejev <armands.malejevs@gmail.com>
Co-authored-by: Jonas Dalesjö <jonas.dalesjo@gmail.com>
Co-authored-by: Shane Mckenna <shanemckennadev@gmail.com>
Co-authored-by: Renaud Chaput <renchap@gmail.com>
Co-authored-by: olivier bouillet <olivier.bouillet@ifeelsmart.com>
Co-authored-by: Omar Diop <accounts@omardiop.com>
Co-authored-by: Olivier Bouillet <62574056+freeboub@users.noreply.github.com>
Co-authored-by: ARTSOFT\csillaj <jenei_csilla@yahoo.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants