iOS DRM Fixes for License Fetching

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

@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

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

Hi @nickfujita ,
I have just tested your function, it has an crash in ios.

@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.

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 @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 it on my prototype app and still get error.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]'
*** First throw call stack:
(0x193512878 0x1a7a68c50 0x193582e1c 0x19358f270 0x193403550 0x1933f5dd0 0x104ae1b6c 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[2]'
terminating with uncaught exception of type NSException

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.  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?

@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.

@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.

@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.

@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.

@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

@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

@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 sources if not provided via the input config parameter licenseServer

@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 sources if not provided via the input config parameter licenseServer

@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 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 :)

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: "..."

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: "..."

@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.

@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.

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

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

@nickfujita I have tried changing your pair but it was not disturbed. Please let me know if I am implementing it the wrong way you would like. Here is my configuration snippet.
<Video
          ref={videoRef}
          source={drmMediaSource}
          drm={
            drmMediaSource.headers ?
              Platform.OS === 'ios'
              ? {
                  type: DrmPlayerComponentConfig.DRMType.FAIRPLAY,
                  certificateUrl: AppConfig.videoCertificateUrl,
                  headers: {
                    Authorization: drmMediaSource.headers.Authorization,
                    'Content-Type': 'application/x-www-form-urlencoded',
                  }
                }
              : {
                  type: DrmPlayerComponentConfig.DRMType.WIDEVINE,
                  licenseServer: DrmPlayerComponentConfig.licenseServer,
                  headers: {
                    'X-AxDRM-Message': drmMediaSource.headers?.Authorization,
                  },
                }
             : undefined
          }/>

@nickfujita I have tried changing your pair but it was not disturbed. Please let me know if I am implementing it the wrong way you would like. Here is my configuration snippet.
<Video
          ref={videoRef}
          source={drmMediaSource}
          drm={
            drmMediaSource.headers ?
              Platform.OS === 'ios'
              ? {
                  type: DrmPlayerComponentConfig.DRMType.FAIRPLAY,
                  certificateUrl: AppConfig.videoCertificateUrl,
                  headers: {
                    Authorization: drmMediaSource.headers.Authorization,
                    'Content-Type': 'application/x-www-form-urlencoded',
                  }
                }
              : {
                  type: DrmPlayerComponentConfig.DRMType.WIDEVINE,
                  licenseServer: DrmPlayerComponentConfig.licenseServer,
                  headers: {
                    'X-AxDRM-Message': drmMediaSource.headers?.Authorization,
                  },
                }
             : undefined
          }/>

@leolaki Could you please confirm that the solution is working for you when using the getLicense callback? I believe it was confirmed to be working by @KrzysztofGastolek . In your first comment your input config was missing the licenseServer field.
Also in the latest example you have provided the licenseServer does not appear to be passed for ios. Could you please try:
{
  type: DrmPlayerComponentConfig.DRMType.FAIRPLAY,
  certificateUrl: AppConfig.videoCertificateUrl,
  licenseServer: DrmPlayerComponentConfig.licenseServer,
  headers: {
    Authorization: drmMediaSource.headers.Authorization,
    'Content-Type': 'application/x-www-form-urlencoded',
  }
}

@leolaki Could you please confirm that the solution is working for you when using the getLicense callback? I believe it was confirmed to be working by @KrzysztofGastolek . In your first comment your input config was missing the licenseServer field.
Also in the latest example you have provided the licenseServer does not appear to be passed for ios. Could you please try:
{
  type: DrmPlayerComponentConfig.DRMType.FAIRPLAY,
  certificateUrl: AppConfig.videoCertificateUrl,
  licenseServer: DrmPlayerComponentConfig.licenseServer,
  headers: {
    Authorization: drmMediaSource.headers.Authorization,
    'Content-Type': 'application/x-www-form-urlencoded',
  }
}

@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.

@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.

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)
              })
          },
        }}
      />

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)
              })
          },
        }}
      />

@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
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}
/>

@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 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..

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

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

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);

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);

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.

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.

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?

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?

@klauszhang
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.

@klauszhang
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.

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 (44b5915f671589caea0df71924b6cffc1858d10b). There was a fix made on the 7th that prevented getLicense from being triggered

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 (44b5915f671589caea0df71924b6cffc1858d10b). There was a fix made on the 7th that prevented getLicense from being triggered

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

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

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

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

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

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

got slightly different log if run on device.
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)

got slightly different log if run on device.
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)

@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"<EMAIL_ADDRESS>
I updated the dependency locally, and found that the getLicense method is being triggered as expected. Could you please confirm.

@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"<EMAIL_ADDRESS>
I updated the dependency locally, and found that the getLicense method is being triggered as expected. Could you please confirm.

@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.

@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.

@nickfujita would you mind taking a look at this issue I'm having? I'm running into trouble with Fairplay and getting an error with receiving a license. I'm doing it without getLicense.
https://github.com/react-native-video/react-native-video/issues/2367

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)
              })
          },
        }}
      />

Hi @klauszhang,
I have the same issue. How did you fixed it? In my code, certificate and license requests never sent.

Related as it breaks some DRM providers: https://github.com/react-native-video/react-native-video/issues/2305

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

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

Sure.

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

<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} />

in getLicense how do I pass the base64?
In this way?
getLicense: (spcString) => {
                const base64spc = Base64.encode(`${contentId}+${certificateUrl}`)

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

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


Error: Failed to find 'minima'

Hi there, followed the README to get this setup with a fresh Jekyll project (literally jekyll new myproject). I get this error after running jekyll s:
Configuration file: /Users/rock/projects/qun/jekyll/_config.yml
PostCSS Server listening on port 8124...
            Source: /Users/rock/projects/qun/jekyll
       Destination: /Users/rock/projects/qun/jekyll/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       Jekyll Feed: Generating feed for posts
PostCSS Error!

Error: Failed to find 'minima'
  in [
    /Users/rock/projects/qun/jekyll
  ]

Minima is the default theme used with Jekyll, but I have no idea why that would be throwing an error. Any tips on how I can get this fixed?
EDIT: Using jekyll 4.2.0, ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-darwin20]

@yazinsai Can you post your configuration files ? I have a working configuration with Tailwind so I can confirm that it works.

Hello, I have the same issue. I want to set up Jekyll with Tailwind and still use the minima theme. But for some reason I cannot import minima like I used to previous to the configuration of PostCSS.
@yazinsai Have you made any progress on this?
Thank you.

@Agusnez yep, got it fixed in my repo here: https://github.com/yazinsai/jekyll-tailwind-template -- should just work

@yazinsai It looks like you have fixed the issue by removing minima entirely from your example.
Is there a way to fix this issue without removing minima?
It looks like the problem is with postcss-import not knowing where to look for the minima files, but the documentation of postcss-import does not clearly explain how to set the paths that are searched.
Any help would be greatly appreciated.

Hey running into same issue here, did anyone figure this out? I want to use tailwind with postcss while still using minima theme.


Neo light theme and contrast

The neo light theme seems to have low contrast on things like search, tabline, and such, making it hard to read. Is this by design? If not, I'd be happy to send a PR to fix some of these, since I imagine these are issues that affect everyone. This involves color selection for various elements, and I'm not sure if you're open to such a PR? Thanks!

Thank you for your feedback and willingness to contribute! I welcome your PR for the light theme, but please make changes in the dev branch first. Feel free to submit it, and I'll review it. I have already attempted to fix the IncSearch issue, so please take a look later.

Great, will push to dev soon.


#322 fix integration tests

fixes #322

removed the autostartup stuff in favor of a single class FullstopIT, that leverages Spring Boot's @WebIntegrationTest annotation to run the whole Fullstop application during a Junit test
moved fullstop module to top-level
removed coveralls
removed docker maven plugin

Current coverage is 41.75%

Merging #323 into master will increase coverage by +0.03% as of a548f64

@@            master    #323   diff @@
======================================
  Files          121     121
  Stmts         2490    2493     +3
  Branches       207     208     +1
  Methods          0       0
======================================
+ Hit           1039    1041     +2
- Partial         39      40     +1
  Missed        1412    1412

Review entire Coverage Diff as of a548f64

Powered by Codecov. Updated on successful CI builds.


jsdom window won't be created

I have problems running the the login sample2. It seems that the jsdom window object won't be created.
	[...]
	$b.browse(function(err, out) {
	  console.log ("creating jsdom window");
	  var window = jsdom(out.result).createWindow();
	  console.log ("created jsdom window");
	  var $ = jquery.create(window);
	  var postdata = {
	    Email  : userdata.email,
	    Passwd : userdata.pass
	  };
	  var url = $("#gaia_loginform").attr("action");
	  // get hidden fields, and register them to post data
	  $("input").each(function(k, el) {
	    var $el = $(el);
	    var name = $el.attr("name"), type = $el.attr("type"), val = $el.val();
	    if (type == "hidden" || type == "submit") postdata[name] = val;
	  });
	  return [url, {
	    data  : postdata, // set post data
	    method: "POST"    // set HTTP method (default: GET)
	  }];
	})
	.after("login"); // browse after browsing with label="login"
	[...]

I added some log statements and never get "created jsdom window" back.
Maybe jsdom changed the API? npm install browser installs jsdom 0.2.9 for me.

Thanks for reporting bugs, and sorry not reply for a long time.
I found this bug is due to junjo's error reporting.
Setting new dependency to the fixed version of junjo (v0.2.6), I updated browser.js (v0.2.4).
I tried jsdom v0.2.9 and it worked well.
try
$ npm update browser
Then please check if it works well in your environment.
I prepared the test script of sample2 (test/manual_login.js).
After setting userdata object in test/accounts/google.json, you can run the test.

Thanks for working on the issue. I still have problems though.
rm -r node_modules
npm install browser
cd node_modules/browser/test

I removed the the first line of manual_login.js ( var userdata = require('./accounts/google'); (as the file is missing in the repo) and just set userdata.email and userdata.pass directly.
node manual_login.js then gave me:
The "sys" module is now called "util". It should have a similar interface.
 redirect count 0 / 10
 cookie
 userAgent (node.js default)
 referer (null)
 -----REQUEST INFORMATION -----------
 access to  https://accounts.google.com/Login
 options { debug: true,
  cookie: '',
  ua: '',
  host: 'accounts.google.com',
  port: 443,
  path: '/Login',
  protocol: 'https',
  body: '' }
 header { 'User-Agent': 'node.js/v0.6.0 (darwin) http.clientRequest',
  Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'ja,en-us;q=0.7,en;q=0.3',
  'Accept-Charset': 'Shift_JIS,utf-8;q=0.7,*;q=0.7',
  'Keep-Alive': 120,
  Connection: 'keep-alive' }
 ------------------------------------

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Cannot read property 'result' of undefined
    at [object Function].<anonymous> (/Users/Oliver/Development/projects/personal/node-duebooks/node_modules/browser/test/manual_login.js:38:22)
    at Array.3 (/Users/Oliver/Development/projects/personal/node-duebooks/node_modules/browser/node_modules/junjo/lib/Junjo.js:307:80)
    at EventEmitter._tickCallback (node.js:192:40)
```

Maybe I'm calling it in a wrong way.

Thanks for your feedback.
I found the problem is that Junjo.js does not work in Node.js v0.6.0.
It is because Function#apply() does not allow arguments object to be passed to the second argument from v0.6.0.
I sometimes pass arguments object to Function#apply() in Junjo.js (or some other libraries, teribble...).
I'm going to fix these invalid use for v0.6.0.
(just inserting Array.prototype.slice.call(arguments))
In Japan it's almost 9:00 AM, so I'll fix this bug and report you again after work.

Sorry, I mistook about the reason of the error.
Forget about the previous comment.
The reason is that  from Node v0.6.0 http modules starts to use "protocol" option.
I've updated the version to v0.2.5, then it can work in Node >=v0.6.
Thanks for reporting.


Submission invitation: validate authorids that are email addresses

This email address https://api2.openreview.net/logs/process?id=BrmOkAg1w5 is passing the submission invitation validation, however the backend is failing because this is not a valid email address.
I suggest using the same regex in both places: API and submission invitation
/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/

Please create a test confirming the email shown in the process function is passing the submission validation and then edit the regex.
Don't use the original, I think accent is not being caught.

Could you also move the post_message calls to the end of the process function here? https://github.com/openreview/openreview-py/blob/master/openreview/venue/process/submission_process.py
So all the necessary objects are created before sending the email notifications, if the post_message fails then we don't need to re-run anything.


Register StorageArrayRecipe in recipe sorter

Closes #101 Didn't tested this because I can't build the mod since I'm getting "class file for mekanism.api.energy.IStrictEnergyAcceptor not found" error while building. But I've made similar PR to Flaxbeard's Steam Power mod and it worked fine.

Thank you ^_^


[Drawer] Allow string widths

There doesn't seem to be any reason that a non-numeric width can't be allowed. Example: '30%', '45vw', etc.

[x] PR has tests / docs demo, and is linted.
[x] Commit and PR titles begin with [ComponentName], and are in imperative form: "[Component] Fix leaky abstraction".
[x] Description explains the issue / use-case resolved, and auto-closes the related issue(s) (http://tr.im/vFqem).

But there is. If you can work around that somehow, then there isn't :grin:

@alitaheri ah thanks for pointing that out. Bummer. I guess i can programmatically determine the width for my use case.