@nativescript/canvas-media 2.0.27 → 2.0.28

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nativescript/canvas-media",
3
- "version": "2.0.27",
3
+ "version": "2.0.28",
4
4
  "description": "Canvas media",
5
5
  "main": "index",
6
6
  "typings": "index.d.ts",
@@ -3,7 +3,9 @@
3
3
  // CanvasMedia
4
4
  //
5
5
  #import "NSCAudioHelper.h"
6
- #import <MobileCoreServices/MobileCoreServices.h>
6
+ #if __has_include(<UniformTypeIdentifiers/UniformTypeIdentifiers.h>)
7
+ #import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
8
+ #endif
7
9
  #import "NSCAudioView.h"
8
10
 
9
11
  @implementation NSCAudioHelper {
@@ -614,17 +616,15 @@
614
616
  }
615
617
  mime = [mime stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
616
618
 
617
- @try {
618
- CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mime, NULL);
619
- if (uti) {
620
- if (UTTypeConformsTo(uti, kUTTypeAudio) || UTTypeConformsTo(uti, kUTTypeAudiovisualContent) || UTTypeConformsTo(uti, kUTTypeMovie)) {
621
- CFRelease(uti);
622
- if ([mime containsString:@"ogg"] || [mime containsString:@"webm"] || [mime containsString:@"opus"]) return @"maybe";
623
- return @"probably";
624
- }
625
- CFRelease(uti);
619
+ #if __has_include(<UniformTypeIdentifiers/UniformTypeIdentifiers.h>)
620
+ if (@available(iOS 14.0, *)) {
621
+ UTType *utType = [UTType typeWithMIMEType:mime];
622
+ if (utType && ([utType conformsToType:UTTypeAudio] || [utType conformsToType:UTTypeAudiovisualContent] || [utType conformsToType:UTTypeMovie])) {
623
+ if ([mime containsString:@"ogg"] || [mime containsString:@"webm"] || [mime containsString:@"opus"]) return @"maybe";
624
+ return @"probably";
626
625
  }
627
- } @catch (NSException *ex) {}
626
+ }
627
+ #endif
628
628
 
629
629
  if ([mime containsString:@"mp3"] || [mime containsString:@"mpeg"] || [mime containsString:@"wav"] || [mime containsString:@"aac"] || [mime containsString:@"m4a"] || [mime containsString:@"flac"]) return @"probably";
630
630
  if ([mime containsString:@"ogg"] || [mime containsString:@"opus"] || [mime containsString:@"webm"]) return @"maybe";
@@ -127,14 +127,17 @@
127
127
  }
128
128
 
129
129
  - (void)setPlaying:(BOOL)playing {
130
+ __weak typeof(self) weakSelf = self;
130
131
  dispatch_async(dispatch_get_main_queue(), ^{
132
+ __strong typeof(weakSelf) strongSelf = weakSelf;
133
+ if (!strongSelf) return;
131
134
  UIImage *img = nil;
132
- if (playing ? _customPauseImage : _customPlayImage) {
133
- img = playing ? _customPauseImage : _customPlayImage;
135
+ if (playing ? strongSelf->_customPauseImage : strongSelf->_customPlayImage) {
136
+ img = playing ? strongSelf->_customPauseImage : strongSelf->_customPlayImage;
134
137
  if (img) {
135
138
  UIImage *templ = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
136
- [_playButton setImage:templ forState:UIControlStateNormal];
137
- if (_iconTintColor) _playButton.tintColor = _iconTintColor;
139
+ [strongSelf->_playButton setImage:templ forState:UIControlStateNormal];
140
+ if (strongSelf->_iconTintColor) strongSelf->_playButton.tintColor = strongSelf->_iconTintColor;
138
141
  return;
139
142
  }
140
143
  }
@@ -143,62 +146,71 @@
143
146
  img = [UIImage systemImageNamed:(playing ? @"pause.fill" : @"play.fill")];
144
147
  if (img) {
145
148
  UIImage *templ = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
146
- [_playButton setImage:templ forState:UIControlStateNormal];
147
- if (_iconTintColor) _playButton.tintColor = _iconTintColor;
149
+ [strongSelf->_playButton setImage:templ forState:UIControlStateNormal];
150
+ if (strongSelf->_iconTintColor) strongSelf->_playButton.tintColor = strongSelf->_iconTintColor;
148
151
  return;
149
152
  }
150
153
  }
151
154
 
152
- UIColor *c = _iconTintColor ?: [UIColor blackColor];
153
- UIImage *fallback = playing ? [self _pauseIconWithSize:CGSizeMake(40,40) color:c] : [self _playIconWithSize:CGSizeMake(40,40) color:c];
155
+ UIColor *c = strongSelf->_iconTintColor ?: [UIColor blackColor];
156
+ UIImage *fallback = playing ? [strongSelf _pauseIconWithSize:CGSizeMake(40,40) color:c] : [strongSelf _playIconWithSize:CGSizeMake(40,40) color:c];
154
157
  if (fallback) {
155
- [_playButton setImage:[fallback imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
156
- if (_iconTintColor) _playButton.tintColor = _iconTintColor;
158
+ [strongSelf->_playButton setImage:[fallback imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
159
+ if (strongSelf->_iconTintColor) strongSelf->_playButton.tintColor = strongSelf->_iconTintColor;
157
160
  }
158
161
  });
159
162
  }
160
163
 
161
164
  - (void)setPlayImage:(UIImage *)image {
162
165
  _customPlayImage = image;
166
+ __weak typeof(self) weakSelf = self;
163
167
  dispatch_async(dispatch_get_main_queue(), ^{
168
+ __strong typeof(weakSelf) strongSelf = weakSelf;
169
+ if (!strongSelf) return;
164
170
  BOOL playing = NO;
165
- if (_helper) {
166
- playing = ([_helper state] == NSCPlayerStatePlaying);
171
+ if (strongSelf->_helper) {
172
+ playing = ([strongSelf->_helper state] == NSCPlayerStatePlaying);
167
173
  }
168
- if (!playing && _customPlayImage) {
169
- UIImage *img = [_customPlayImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
170
- [_playButton setImage:img forState:UIControlStateNormal];
171
- if (_iconTintColor) _playButton.tintColor = _iconTintColor;
174
+ if (!playing && strongSelf->_customPlayImage) {
175
+ UIImage *img = [strongSelf->_customPlayImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
176
+ [strongSelf->_playButton setImage:img forState:UIControlStateNormal];
177
+ if (strongSelf->_iconTintColor) strongSelf->_playButton.tintColor = strongSelf->_iconTintColor;
172
178
  }
173
179
  });
174
180
  }
175
181
 
176
182
  - (void)setPauseImage:(UIImage *)image {
177
183
  _customPauseImage = image;
184
+ __weak typeof(self) weakSelf = self;
178
185
  dispatch_async(dispatch_get_main_queue(), ^{
186
+ __strong typeof(weakSelf) strongSelf = weakSelf;
187
+ if (!strongSelf) return;
179
188
  BOOL playing = NO;
180
- if (_helper) {
181
- playing = ([_helper state] == NSCPlayerStatePlaying);
189
+ if (strongSelf->_helper) {
190
+ playing = ([strongSelf->_helper state] == NSCPlayerStatePlaying);
182
191
  }
183
- if (playing && _customPauseImage) {
184
- UIImage *img = [_customPauseImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
185
- [_playButton setImage:img forState:UIControlStateNormal];
186
- if (_iconTintColor) _playButton.tintColor = _iconTintColor;
192
+ if (playing && strongSelf->_customPauseImage) {
193
+ UIImage *img = [strongSelf->_customPauseImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
194
+ [strongSelf->_playButton setImage:img forState:UIControlStateNormal];
195
+ if (strongSelf->_iconTintColor) strongSelf->_playButton.tintColor = strongSelf->_iconTintColor;
187
196
  }
188
197
  });
189
198
  }
190
199
 
191
200
  - (void)setIconTintColor:(UIColor *)color {
192
201
  _iconTintColor = color;
202
+ __weak typeof(self) weakSelf = self;
193
203
  dispatch_async(dispatch_get_main_queue(), ^{
194
- if (_iconTintColor) {
195
- _playButton.tintColor = _iconTintColor;
204
+ __strong typeof(weakSelf) strongSelf = weakSelf;
205
+ if (!strongSelf) return;
206
+ if (strongSelf->_iconTintColor) {
207
+ strongSelf->_playButton.tintColor = strongSelf->_iconTintColor;
196
208
  }
197
209
  BOOL playing = NO;
198
- if (_helper) {
199
- playing = ([_helper state] == NSCPlayerStatePlaying);
210
+ if (strongSelf->_helper) {
211
+ playing = ([strongSelf->_helper state] == NSCPlayerStatePlaying);
200
212
  }
201
- [self setPlaying:playing];
213
+ [strongSelf setPlaying:playing];
202
214
  });
203
215
  }
204
216
 
@@ -243,17 +255,20 @@
243
255
  }
244
256
 
245
257
  - (void)setDuration:(double)seconds {
258
+ __weak typeof(self) weakSelf = self;
246
259
  dispatch_async(dispatch_get_main_queue(), ^{
247
- _slider.minimumValue = 0;
260
+ __strong typeof(weakSelf) strongSelf = weakSelf;
261
+ if (!strongSelf) return;
262
+ strongSelf->_slider.minimumValue = 0;
248
263
  if (seconds > 0) {
249
- _slider.maximumValue = (float)seconds;
264
+ strongSelf->_slider.maximumValue = (float)seconds;
250
265
  } else {
251
- _slider.maximumValue = 1.0f;
266
+ strongSelf->_slider.maximumValue = 1.0f;
252
267
  }
253
- _durationSeconds = seconds;
254
- _slider.enabled = (!isnan(seconds) && seconds > 0);
255
- if (_slider.value > _slider.maximumValue) _slider.value = _slider.maximumValue;
256
- [self updateTimeLabelWithCurrent:_slider.value duration:_durationSeconds];
268
+ strongSelf->_durationSeconds = seconds;
269
+ strongSelf->_slider.enabled = (!isnan(seconds) && seconds > 0);
270
+ if (strongSelf->_slider.value > strongSelf->_slider.maximumValue) strongSelf->_slider.value = strongSelf->_slider.maximumValue;
271
+ [strongSelf updateTimeLabelWithCurrent:strongSelf->_slider.value duration:strongSelf->_durationSeconds];
257
272
  });
258
273
  }
259
274
 
@@ -5,7 +5,9 @@
5
5
  // Created by Osei Fortune on 20/05/2025.
6
6
  //
7
7
  #import "NSCVideoHelper.h"
8
- #import <MobileCoreServices/MobileCoreServices.h>
8
+ #if __has_include(<UniformTypeIdentifiers/UniformTypeIdentifiers.h>)
9
+ #import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
10
+ #endif
9
11
  #import "NSCVideoHelper+Internal.h"
10
12
 
11
13
  @implementation NSCVideoHelper {
@@ -79,21 +81,30 @@
79
81
  __weak typeof(self) weakSelf = self;
80
82
  [self.asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
81
83
  dispatch_async(dispatch_get_main_queue(), ^{
82
- __strong typeof(self) strongSelf = weakSelf;
83
- if (!strongSelf) return;
84
-
85
- AVAssetTrack *videoTrack = [[weakSelf.asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
86
- strongSelf->_videoSize = videoTrack.naturalSize;
84
+ __strong typeof(weakSelf) strongSelf = weakSelf;
85
+ if (!strongSelf) return;
86
+
87
+ AVAssetTrack *videoTrack = [[strongSelf.asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
88
+ strongSelf->_videoSize = videoTrack ? videoTrack.naturalSize : CGSizeZero;
87
89
 
88
- float fps = videoTrack.nominalFrameRate ?: 30.0;
90
+ float fps = (videoTrack && videoTrack.nominalFrameRate > 0) ? videoTrack.nominalFrameRate : 30.0f;
89
91
  CMTime interval = CMTimeMake(1, (int32_t)fps);
90
- weakSelf.playbackFramesObserver = [weakSelf.player addPeriodicTimeObserverForInterval:interval queue:nil usingBlock:^(CMTime time) {
91
- if (weakSelf.state == NSCPlayerStatePlaying) {
92
- [weakSelf.listener onVideoFrameCallback];
92
+
93
+ if (strongSelf.playbackFramesObserver) {
94
+ [strongSelf.player removeTimeObserver:strongSelf.playbackFramesObserver];
95
+ strongSelf.playbackFramesObserver = nil;
96
+ }
97
+
98
+ __weak typeof(strongSelf) weakFrameSelf = strongSelf;
99
+ strongSelf.playbackFramesObserver = [strongSelf.player addPeriodicTimeObserverForInterval:interval queue:nil usingBlock:^(CMTime time) {
100
+ __strong typeof(weakFrameSelf) frameSelf = weakFrameSelf;
101
+ if (!frameSelf) return;
102
+ if (frameSelf.state == NSCPlayerStatePlaying) {
103
+ [frameSelf.listener onVideoFrameCallback];
93
104
  }
94
105
  }];
95
106
 
96
- AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:weakSelf.asset];
107
+ AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:strongSelf.asset];
97
108
 
98
109
  strongSelf->_currentItem = item;
99
110
 
@@ -112,10 +123,11 @@
112
123
  [item addObserver:strongSelf forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
113
124
  [item addObserver:strongSelf forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];
114
125
 
126
+ __weak typeof(strongSelf) weakPlayEndSelf = strongSelf;
115
127
  strongSelf->_playEndNotificationId = [[NSNotificationCenter defaultCenter]
116
128
  addObserverForName:AVPlayerItemDidPlayToEndTimeNotification
117
129
  object:item queue:nil usingBlock:^(NSNotification *note) {
118
- __strong typeof(strongSelf) innerSelf = strongSelf;
130
+ __strong typeof(weakPlayEndSelf) innerSelf = weakPlayEndSelf;
119
131
  if (!innerSelf) return;
120
132
  if (innerSelf->_isLoop) {
121
133
  [innerSelf->_player seekToTime:kCMTimeZero];
@@ -133,27 +145,6 @@
133
145
  if (strongSelf.autoplay) {
134
146
  [strongSelf play];
135
147
  }
136
-
137
- [item addObserver:strongSelf forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
138
- [item addObserver:strongSelf forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];
139
-
140
- strongSelf->_playEndNotificationId = [[NSNotificationCenter defaultCenter]
141
- addObserverForName:AVPlayerItemDidPlayToEndTimeNotification
142
- object:item queue:nil usingBlock:^(NSNotification *note) {
143
- if (weakSelf != NULL && weakSelf.isLoop) {
144
- [weakSelf.player seekToTime:kCMTimeZero];
145
- [weakSelf.player play];
146
- weakSelf.state = NSCPlayerStatePlaying;
147
- [weakSelf.listener onStateChange:NSCPlayerStatePlaying];
148
- }
149
- }];
150
-
151
- [weakSelf.player replaceCurrentItemWithPlayerItem:item];
152
- weakSelf.readyState = NSCPlayerReadyStateHaveMetadata;
153
- [weakSelf performSelectorOnMainThread:@selector(_scheduleFirstFrameCheck) withObject:nil waitUntilDone:NO];
154
- if (weakSelf.autoplay) {
155
- [weakSelf play];
156
- }
157
148
  });
158
149
  }];
159
150
  }
@@ -219,17 +210,15 @@
219
210
  }
220
211
  mime = [mime stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
221
212
 
222
- @try {
223
- CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mime, NULL);
224
- if (uti) {
225
- if (UTTypeConformsTo(uti, kUTTypeVideo) || UTTypeConformsTo(uti, kUTTypeAudiovisualContent)) {
226
- CFRelease(uti);
227
- if ([mime containsString:@"webm"] || [mime containsString:@"vp8"] || [mime containsString:@"vp9"] || [mime containsString:@"ogg"]) return @"maybe";
228
- return @"probably";
229
- }
230
- CFRelease(uti);
213
+ #if __has_include(<UniformTypeIdentifiers/UniformTypeIdentifiers.h>)
214
+ if (@available(iOS 14.0, *)) {
215
+ UTType *utType = [UTType typeWithMIMEType:mime];
216
+ if (utType && ([utType conformsToType:UTTypeVideo] || [utType conformsToType:UTTypeAudiovisualContent])) {
217
+ if ([mime containsString:@"webm"] || [mime containsString:@"vp8"] || [mime containsString:@"vp9"] || [mime containsString:@"ogg"]) return @"maybe";
218
+ return @"probably";
231
219
  }
232
- } @catch (NSException *ex) {}
220
+ }
221
+ #endif
233
222
 
234
223
  if ([mime containsString:@"mp4"] || [mime containsString:@"mpeg"] || [mime containsString:@"h264"] || [mime containsString:@"video/mp4"]) return @"probably";
235
224
  if ([mime containsString:@"webm"] || [mime containsString:@"vp8"] || [mime containsString:@"vp9"] || [mime containsString:@"video/webm"]) return @"maybe";
@@ -320,46 +309,49 @@
320
309
  }
321
310
 
322
311
  - (void)load {
312
+ __weak typeof(self) weakSelf = self;
323
313
  dispatch_async(dispatch_get_main_queue(), ^{
314
+ __strong typeof(weakSelf) strongSelf = weakSelf;
315
+ if (!strongSelf) return;
324
316
  @try {
325
- [self pause];
317
+ [strongSelf pause];
326
318
 
327
- if (self.playbackTimeObserver) {
328
- [self.player removeTimeObserver:self.playbackTimeObserver];
329
- self.playbackTimeObserver = nil;
319
+ if (strongSelf.playbackTimeObserver) {
320
+ [strongSelf.player removeTimeObserver:strongSelf.playbackTimeObserver];
321
+ strongSelf.playbackTimeObserver = nil;
330
322
  }
331
323
 
332
- if (self.playbackFramesObserver) {
333
- [self.player removeTimeObserver:self.playbackFramesObserver];
334
- self.playbackFramesObserver = nil;
324
+ if (strongSelf.playbackFramesObserver) {
325
+ [strongSelf.player removeTimeObserver:strongSelf.playbackFramesObserver];
326
+ strongSelf.playbackFramesObserver = nil;
335
327
  }
336
328
 
337
- if (_playEndNotificationId) {
338
- [[NSNotificationCenter defaultCenter] removeObserver:_playEndNotificationId];
339
- _playEndNotificationId = nil;
329
+ if (strongSelf->_playEndNotificationId) {
330
+ [[NSNotificationCenter defaultCenter] removeObserver:strongSelf->_playEndNotificationId];
331
+ strongSelf->_playEndNotificationId = nil;
340
332
  }
341
333
 
342
- if (self.currentItem) {
334
+ if (strongSelf.currentItem) {
343
335
  @try {
344
- [self.currentItem removeObserver:self forKeyPath:@"status"];
336
+ [strongSelf.currentItem removeObserver:strongSelf forKeyPath:@"status"];
345
337
  } @catch (NSException *exception) {}
346
338
  @try {
347
- [self.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
339
+ [strongSelf.currentItem removeObserver:strongSelf forKeyPath:@"loadedTimeRanges"];
348
340
  } @catch (NSException *exception) {}
349
341
  }
350
342
 
351
- if (self.assetOutput) {
352
- [self.assetOutput setDelegate:nil queue:NULL];
343
+ if (strongSelf.assetOutput) {
344
+ [strongSelf.assetOutput setDelegate:nil queue:NULL];
353
345
  }
354
346
 
355
- [self.player replaceCurrentItemWithPlayerItem:nil];
347
+ [strongSelf.player replaceCurrentItemWithPlayerItem:nil];
356
348
 
357
- self.loadedDataFired = NO;
349
+ strongSelf.loadedDataFired = NO;
358
350
 
359
- if (self.currentSrc && self.currentSrc.length > 0) {
360
- NSString *src = [self.currentSrc copy];
361
- self.currentSrc = nil;
362
- [self setSrc:src];
351
+ if (strongSelf.currentSrc && strongSelf.currentSrc.length > 0) {
352
+ NSString *src = [strongSelf.currentSrc copy];
353
+ strongSelf.currentSrc = nil;
354
+ [strongSelf setSrc:src];
363
355
  }
364
356
  } @catch (NSException *ex) {
365
357
  NSLog(@"NSCVideoHelper load() error: %@", ex);