@nativescript/canvas-media 2.0.27 → 2.0.29
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
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
// CanvasMedia
|
|
4
4
|
//
|
|
5
5
|
#import "NSCAudioHelper.h"
|
|
6
|
-
#
|
|
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
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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
|
-
}
|
|
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 ? [
|
|
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
|
-
|
|
195
|
-
|
|
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
|
-
[
|
|
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
|
-
|
|
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
|
-
[
|
|
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
|
-
#
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
AVAssetTrack *videoTrack = [[
|
|
86
|
-
|
|
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
|
|
90
|
+
float fps = (videoTrack && videoTrack.nominalFrameRate > 0) ? videoTrack.nominalFrameRate : 30.0f;
|
|
89
91
|
CMTime interval = CMTimeMake(1, (int32_t)fps);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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:
|
|
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(
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
}
|
|
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
|
-
[
|
|
317
|
+
[strongSelf pause];
|
|
326
318
|
|
|
327
|
-
if (
|
|
328
|
-
[
|
|
329
|
-
|
|
319
|
+
if (strongSelf.playbackTimeObserver) {
|
|
320
|
+
[strongSelf.player removeTimeObserver:strongSelf.playbackTimeObserver];
|
|
321
|
+
strongSelf.playbackTimeObserver = nil;
|
|
330
322
|
}
|
|
331
323
|
|
|
332
|
-
if (
|
|
333
|
-
[
|
|
334
|
-
|
|
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 (
|
|
334
|
+
if (strongSelf.currentItem) {
|
|
343
335
|
@try {
|
|
344
|
-
[
|
|
336
|
+
[strongSelf.currentItem removeObserver:strongSelf forKeyPath:@"status"];
|
|
345
337
|
} @catch (NSException *exception) {}
|
|
346
338
|
@try {
|
|
347
|
-
[
|
|
339
|
+
[strongSelf.currentItem removeObserver:strongSelf forKeyPath:@"loadedTimeRanges"];
|
|
348
340
|
} @catch (NSException *exception) {}
|
|
349
341
|
}
|
|
350
342
|
|
|
351
|
-
if (
|
|
352
|
-
[
|
|
343
|
+
if (strongSelf.assetOutput) {
|
|
344
|
+
[strongSelf.assetOutput setDelegate:nil queue:NULL];
|
|
353
345
|
}
|
|
354
346
|
|
|
355
|
-
[
|
|
347
|
+
[strongSelf.player replaceCurrentItemWithPlayerItem:nil];
|
|
356
348
|
|
|
357
|
-
|
|
349
|
+
strongSelf.loadedDataFired = NO;
|
|
358
350
|
|
|
359
|
-
if (
|
|
360
|
-
NSString *src = [
|
|
361
|
-
|
|
362
|
-
[
|
|
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);
|