react-native-unified-player 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#import <React/RCTEventEmitter.h>
|
|
2
2
|
#import <React/RCTBridgeModule.h>
|
|
3
|
-
#import <
|
|
3
|
+
#import <AVFoundation/AVFoundation.h> // Import MobileVLCKit
|
|
4
4
|
|
|
5
5
|
// Forward declaration for UnifiedPlayerUIView
|
|
6
6
|
@class UnifiedPlayerUIView;
|
|
@@ -530,10 +530,75 @@
|
|
|
530
530
|
#pragma mark - Recording (Placeholder - can be implemented later)
|
|
531
531
|
|
|
532
532
|
- (void)captureFrameWithCompletion:(void (^)(NSString * _Nullable base64String, NSError * _Nullable error))completion {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
533
|
+
if (!completion) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (!_playerItem || _playerItem.status != AVPlayerItemStatusReadyToPlay) {
|
|
538
|
+
completion(nil, [NSError errorWithDomain:@"UnifiedPlayer"
|
|
539
|
+
code:1
|
|
540
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Player item not ready"}]);
|
|
541
|
+
return;
|
|
536
542
|
}
|
|
543
|
+
|
|
544
|
+
if (!_playerLayer) {
|
|
545
|
+
completion(nil, [NSError errorWithDomain:@"UnifiedPlayer"
|
|
546
|
+
code:2
|
|
547
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Player layer not available"}]);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Use AVAssetImageGenerator to capture the current frame
|
|
552
|
+
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:_playerItem.asset];
|
|
553
|
+
imageGenerator.appliesPreferredTrackTransform = YES;
|
|
554
|
+
imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
|
|
555
|
+
imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
|
|
556
|
+
|
|
557
|
+
CMTime currentTime = _player.currentTime;
|
|
558
|
+
if (!CMTIME_IS_VALID(currentTime)) {
|
|
559
|
+
currentTime = kCMTimeZero;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Generate the image
|
|
563
|
+
[imageGenerator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:currentTime]]
|
|
564
|
+
completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
|
|
565
|
+
if (error) {
|
|
566
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
567
|
+
completion(nil, error);
|
|
568
|
+
});
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (result != AVAssetImageGeneratorSucceeded || !image) {
|
|
573
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
574
|
+
completion(nil, [NSError errorWithDomain:@"UnifiedPlayer"
|
|
575
|
+
code:3
|
|
576
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Failed to generate image"}]);
|
|
577
|
+
});
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Convert CGImage to UIImage
|
|
582
|
+
UIImage *uiImage = [UIImage imageWithCGImage:image];
|
|
583
|
+
|
|
584
|
+
// Convert to JPEG data
|
|
585
|
+
NSData *imageData = UIImageJPEGRepresentation(uiImage, 0.8);
|
|
586
|
+
if (!imageData) {
|
|
587
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
588
|
+
completion(nil, [NSError errorWithDomain:@"UnifiedPlayer"
|
|
589
|
+
code:4
|
|
590
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Failed to convert image to JPEG"}]);
|
|
591
|
+
});
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Encode to base64
|
|
596
|
+
NSString *base64String = [imageData base64EncodedStringWithOptions:0];
|
|
597
|
+
|
|
598
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
599
|
+
completion(base64String, nil);
|
|
600
|
+
});
|
|
601
|
+
}];
|
|
537
602
|
}
|
|
538
603
|
|
|
539
604
|
- (void)captureFrameForRecording {
|