Add audio support.

This commit is contained in:
PonyCui
2018-10-18 17:37:18 +08:00
parent 702f91dd4d
commit e8aea48061
14 changed files with 352 additions and 82 deletions

View File

@@ -1,5 +1,5 @@
PODS:
- Protobuf (3.4.0)
- Protobuf (3.6.1)
- React/ART (0.45.1):
- React/Core
- React/Core (0.45.1):
@@ -28,7 +28,7 @@ PODS:
- React/RCTWebSocket (0.45.1):
- React/Core
- SSZipArchive (1.8.1)
- Yoga (1.6.0)
- Yoga (1.9.0)
DEPENDENCIES:
- Protobuf (~> 3.4)
@@ -46,16 +46,22 @@ DEPENDENCIES:
- SSZipArchive (~> 1.8.1)
- Yoga
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- Protobuf
- SSZipArchive
- Yoga
EXTERNAL SOURCES:
React:
:podspec: https://raw.githubusercontent.com/yyued/react-native-runtime-ios/0.45.1/React.podspec
SPEC CHECKSUMS:
Protobuf: 03eef2ee0b674770735cf79d9c4d3659cf6908e8
Protobuf: 1eb9700044745f00181c136ef21b8ff3ad5a0fd5
React: 505e0132cd9aaba1a56e47ef509220dd794ec9be
SSZipArchive: 04547dfa448be5ed7ecbaf7eaf8a6e9eb9b42997
Yoga: 81670877477311136b1b3f69a6307ce62e1c89cf
Yoga: aaae8abea68951f60bee05f6277d3eed90bb91bb
PODFILE CHECKSUM: b7d71960f4fe0b08fd7d4651b412bb8bec6c19f2
COCOAPODS: 1.3.1
COCOAPODS: 1.5.3

View File

@@ -8,6 +8,9 @@
/* Begin PBXBuildFile section */
4B62B1C5E6CE2BE2D914927B /* libPods-SVGAPlayer React.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 92332F7A897BF4379D765B05 /* libPods-SVGAPlayer React.a */; };
63712E6521787950001AE014 /* heartbeat.svga in Resources */ = {isa = PBXBuildFile; fileRef = 63712E6421787950001AE014 /* heartbeat.svga */; };
63712E6821787A45001AE014 /* SVGAAudioEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 63712E6721787A45001AE014 /* SVGAAudioEntity.m */; };
63E817012178809D001D2D62 /* SVGAAudioLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E817002178809D001D2D62 /* SVGAAudioLayer.m */; };
80D4C7254846B96B9C6EED83 /* libPods-SVGAPlayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DDA5FF396660C7C932DF9B8 /* libPods-SVGAPlayer.a */; };
904D41F81D223DD20085A21A /* SVGABezierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 904D41F71D223DD20085A21A /* SVGABezierPath.m */; };
9052FC631E6EB8D4007BC925 /* SVGAExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9052FC621E6EB8D4007BC925 /* SVGAExporter.m */; };
@@ -55,6 +58,11 @@
/* Begin PBXFileReference section */
1DDA5FF396660C7C932DF9B8 /* libPods-SVGAPlayer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SVGAPlayer.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2EF4851C027B3C0E45E3C5C0 /* Pods-SVGAPlayer React.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SVGAPlayer React.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SVGAPlayer React/Pods-SVGAPlayer React.debug.xcconfig"; sourceTree = "<group>"; };
63712E6421787950001AE014 /* heartbeat.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = heartbeat.svga; sourceTree = "<group>"; };
63712E6621787A45001AE014 /* SVGAAudioEntity.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAAudioEntity.h; sourceTree = "<group>"; };
63712E6721787A45001AE014 /* SVGAAudioEntity.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SVGAAudioEntity.m; sourceTree = "<group>"; };
63E816FF2178809D001D2D62 /* SVGAAudioLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAAudioLayer.h; sourceTree = "<group>"; };
63E817002178809D001D2D62 /* SVGAAudioLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SVGAAudioLayer.m; sourceTree = "<group>"; };
8AD65028FA2D122A34DC4A63 /* Pods-SVGAPlayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SVGAPlayer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SVGAPlayer/Pods-SVGAPlayer.debug.xcconfig"; sourceTree = "<group>"; };
904D41F61D223DD20085A21A /* SVGABezierPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGABezierPath.h; sourceTree = "<group>"; };
904D41F71D223DD20085A21A /* SVGABezierPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGABezierPath.m; sourceTree = "<group>"; };
@@ -193,6 +201,8 @@
90A676FC1D13A82A008A69F3 /* SVGAParser.m */,
90A677011D13AE19008A69F3 /* SVGAVideoEntity.h */,
90A677021D13AE19008A69F3 /* SVGAVideoEntity.m */,
63712E6621787A45001AE014 /* SVGAAudioEntity.h */,
63712E6721787A45001AE014 /* SVGAAudioEntity.m */,
90A364D51E5AECBD009347F1 /* SVGAVideoSpriteEntity.h */,
90A364D61E5AECBD009347F1 /* SVGAVideoSpriteEntity.m */,
90A364D81E5AED04009347F1 /* SVGAVideoSpriteFrameEntity.h */,
@@ -203,6 +213,8 @@
90A364D01E5AEC11009347F1 /* SVGABitmapLayer.m */,
90A364D21E5AEC1B009347F1 /* SVGAVectorLayer.h */,
90A364D31E5AEC1C009347F1 /* SVGAVectorLayer.m */,
63E816FF2178809D001D2D62 /* SVGAAudioLayer.h */,
63E817002178809D001D2D62 /* SVGAAudioLayer.m */,
90A677041D13BF77008A69F3 /* SVGAPlayer.h */,
90A677051D13BF77008A69F3 /* SVGAPlayer.m */,
90DB59B31F96026E00894727 /* SVGAImageView.h */,
@@ -227,6 +239,7 @@
90D7C9FA1F7E2AA3006E74F0 /* Samples */ = {
isa = PBXGroup;
children = (
63712E6421787950001AE014 /* heartbeat.svga */,
90D7CA1A1F7FB114006E74F0 /* rose_1.5.0.svga */,
90D7CA191F7FB114006E74F0 /* rose_2.0.0.svga */,
);
@@ -263,8 +276,6 @@
90A676D91D13A6DF008A69F3 /* Sources */,
90A676DA1D13A6DF008A69F3 /* Frameworks */,
90A676DB1D13A6DF008A69F3 /* Resources */,
90CFF6F7E27D61F7415658A8 /* [CP] Embed Pods Frameworks */,
30824E0A5B95B78BA26133C9 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -283,8 +294,6 @@
90CB64CB1EF290F400DAA382 /* Sources */,
90CB64DA1EF290F400DAA382 /* Frameworks */,
90CB64DC1EF290F400DAA382 /* Resources */,
97FF02AF76FF679B16FE6BE5 /* [CP] Embed Pods Frameworks */,
954F7371F8B4658670CCA7D4 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -306,7 +315,7 @@
TargetAttributes = {
90A676DC1D13A6DF008A69F3 = {
CreatedOnToolsVersion = 7.3;
DevelopmentTeam = 8M2FQ87SLP;
DevelopmentTeam = 544P5CH38C;
};
90CB64C91EF290F400DAA382 = {
DevelopmentTeam = 8M2FQ87SLP;
@@ -339,6 +348,7 @@
files = (
90A676F01D13A6DF008A69F3 /* LaunchScreen.storyboard in Resources */,
90A676ED1D13A6DF008A69F3 /* Assets.xcassets in Resources */,
63712E6521787950001AE014 /* heartbeat.svga in Resources */,
90A676EB1D13A6DF008A69F3 /* Main.storyboard in Resources */,
90CB64F91EF297E800DAA382 /* SVGAPlayer React-Info.plist in Resources */,
90D7CA1C1F7FB114006E74F0 /* rose_1.5.0.svga in Resources */,
@@ -359,21 +369,6 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
30824E0A5B95B78BA26133C9 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SVGAPlayer/Pods-SVGAPlayer-resources.sh\"\n";
showEnvVarsInLog = 0;
};
890FC763F2C82314110A5C8F /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -392,51 +387,6 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
90CFF6F7E27D61F7415658A8 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SVGAPlayer/Pods-SVGAPlayer-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
954F7371F8B4658670CCA7D4 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SVGAPlayer React/Pods-SVGAPlayer React-resources.sh\"\n";
showEnvVarsInLog = 0;
};
97FF02AF76FF679B16FE6BE5 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SVGAPlayer React/Pods-SVGAPlayer React-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
CD70B01EE331E392E355CD26 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -466,6 +416,8 @@
9052FC631E6EB8D4007BC925 /* SVGAExporter.m in Sources */,
90A677031D13AE19008A69F3 /* SVGAVideoEntity.m in Sources */,
90A364DA1E5AED04009347F1 /* SVGAVideoSpriteFrameEntity.m in Sources */,
63712E6821787A45001AE014 /* SVGAAudioEntity.m in Sources */,
63E817012178809D001D2D62 /* SVGAAudioLayer.m in Sources */,
90A364D11E5AEC11009347F1 /* SVGABitmapLayer.m in Sources */,
904D41F81D223DD20085A21A /* SVGABezierPath.m in Sources */,
90A364D71E5AECBD009347F1 /* SVGAVideoSpriteEntity.m in Sources */,
@@ -613,6 +565,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = 544P5CH38C;
INFOPLIST_FILE = SVGAPlayer/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -629,6 +582,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
DEVELOPMENT_TEAM = 544P5CH38C;
INFOPLIST_FILE = SVGAPlayer/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";

Binary file not shown.

View File

@@ -59,6 +59,12 @@ static SVGAParser *parser;
[self.aPlayer startAnimation];
}
} failureBlock:nil];
// [parser parseWithNamed:@"heartbeat" inBundle:nil completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
// if (videoItem != nil) {
// self.aPlayer.videoItem = videoItem;
// [self.aPlayer startAnimation];
// }
// } failureBlock:nil];
}
- (SVGAPlayer *)aPlayer {

22
Source/SVGAAudioEntity.h Normal file
View File

@@ -0,0 +1,22 @@
//
// SVGAAudioEntity.h
// SVGAPlayer
//
// Created by PonyCui on 2018/10/18.
// Copyright © 2018年 UED Center. All rights reserved.
//
#import <Foundation/Foundation.h>
@class SVGAProtoAudioEntity;
@interface SVGAAudioEntity : NSObject
@property (nonatomic, readonly) NSString *audioKey;
@property (nonatomic, readonly) NSInteger startFrame;
@property (nonatomic, readonly) NSInteger endFrame;
@property (nonatomic, readonly) NSInteger startTime;
- (instancetype)initWithProtoObject:(SVGAProtoAudioEntity *)protoObject;
@end

34
Source/SVGAAudioEntity.m Normal file
View File

@@ -0,0 +1,34 @@
//
// SVGAAudioEntity.m
// SVGAPlayer
//
// Created by PonyCui on 2018/10/18.
// Copyright © 2018 UED Center. All rights reserved.
//
#import "SVGAAudioEntity.h"
#import "Svga.pbobjc.h"
@interface SVGAAudioEntity ()
@property (nonatomic, readwrite) NSString *audioKey;
@property (nonatomic, readwrite) NSInteger startFrame;
@property (nonatomic, readwrite) NSInteger endFrame;
@property (nonatomic, readwrite) NSInteger startTime;
@end
@implementation SVGAAudioEntity
- (instancetype)initWithProtoObject:(SVGAProtoAudioEntity *)protoObject {
self = [super init];
if (self) {
_audioKey = protoObject.audioKey;
_startFrame = protoObject.startFrame;
_endFrame = protoObject.endFrame;
_startTime = protoObject.startTime;
}
return self;
}
@end

21
Source/SVGAAudioLayer.h Normal file
View File

@@ -0,0 +1,21 @@
//
// SVGAAudioLayer.h
// SVGAPlayer
//
// Created by PonyCui on 2018/10/18.
// Copyright © 2018年 UED Center. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@class SVGAAudioEntity, SVGAVideoEntity;
@interface SVGAAudioLayer : NSObject
@property (nonatomic, readonly) AVAudioPlayer *audioPlayer;
@property (nonatomic, readonly) SVGAAudioEntity *audioItem;
- (instancetype)initWithAudioItem:(SVGAAudioEntity *)audioItem videoItem:(SVGAVideoEntity *)videoItem;
@end

37
Source/SVGAAudioLayer.m Normal file
View File

@@ -0,0 +1,37 @@
//
// SVGAAudioLayer.m
// SVGAPlayer
//
// Created by PonyCui on 2018/10/18.
// Copyright © 2018 UED Center. All rights reserved.
//
#import "SVGAAudioLayer.h"
#import "SVGAAudioEntity.h"
#import "SVGAVideoEntity.h"
@interface SVGAAudioLayer ()
@property (nonatomic, readwrite) AVAudioPlayer *audioPlayer;
@property (nonatomic, readwrite) SVGAAudioEntity *audioItem;
@end
@implementation SVGAAudioLayer
- (instancetype)initWithAudioItem:(SVGAAudioEntity *)audioItem videoItem:(SVGAVideoEntity *)videoItem
{
self = [super init];
if (self) {
_audioItem = audioItem;
if (audioItem.audioKey != nil && videoItem.audiosData[audioItem.audioKey] != nil) {
_audioPlayer = [[AVAudioPlayer alloc] initWithData:videoItem.audiosData[audioItem.audioKey]
fileTypeHint:@"mp3"
error:NULL];
[_audioPlayer prepareToPlay];
}
}
return self;
}
@end

View File

@@ -123,6 +123,7 @@ static NSOperationQueue *unzipQueue;
SVGAVideoEntity *videoItem = [[SVGAVideoEntity alloc] initWithProtoObject:protoObject cacheDir:cacheDir];
[videoItem resetImagesWithProtoObject:protoObject];
[videoItem resetSpritesWithProtoObject:protoObject];
[videoItem resetAudiosWithProtoObject:protoObject];
[videoItem saveCache:cacheKey];
if (completionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
@@ -198,6 +199,7 @@ static NSOperationQueue *unzipQueue;
SVGAVideoEntity *videoItem = [[SVGAVideoEntity alloc] initWithProtoObject:protoObject cacheDir:@""];
[videoItem resetImagesWithProtoObject:protoObject];
[videoItem resetSpritesWithProtoObject:protoObject];
[videoItem resetAudiosWithProtoObject:protoObject];
[videoItem saveCache:cacheKey];
if (completionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{

View File

@@ -13,10 +13,13 @@
#import "SVGAContentLayer.h"
#import "SVGABitmapLayer.h"
#import "SVGAVectorLayer.h"
#import "SVGAAudioLayer.h"
#import "SVGAAudioEntity.h"
@interface SVGAPlayer ()
@property (nonatomic, strong) CALayer *drawLayer;
@property (nonatomic, strong) NSArray<SVGAAudioLayer *> *audioLayers;
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic, assign) NSInteger currentFrame;
@property (nonatomic, copy) NSDictionary<NSString *, UIImage *> *dynamicObjects;
@@ -25,6 +28,7 @@
@property (nonatomic, copy) NSDictionary<NSString *, NSNumber *> *dynamicHiddens;
@property (nonatomic, assign) int loopCount;
@property (nonatomic, assign) NSRange currentRange;
@property (nonatomic, assign) BOOL forwardAnimating;
@property (nonatomic, assign) BOOL reversing;
@end
@@ -53,6 +57,7 @@
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(next)];
self.displayLink.frameInterval = 60 / self.videoItem.FPS;
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
self.forwardAnimating = !self.reversing;
}
- (void)startAnimationWithRange:(NSRange)range reverse:(BOOL)reverse {
@@ -76,12 +81,14 @@
}
- (void)stopAnimation:(BOOL)clear {
self.forwardAnimating = NO;
if (self.displayLink != nil) {
[self.displayLink invalidate];
}
if (clear) {
[self clear];
}
[self clearAudios];
self.displayLink = nil;
}
@@ -89,6 +96,12 @@
[self.drawLayer removeFromSuperlayer];
}
- (void)clearAudios {
for (SVGAAudioLayer *layer in self.audioLayers) {
[layer.audioPlayer stop];
}
}
- (void)stepToFrame:(NSInteger)frame andPlay:(BOOL)andPlay {
if (frame >= self.videoItem.frames || frame < 0) {
return;
@@ -149,6 +162,12 @@
}
}];
[self.layer addSublayer:self.drawLayer];
NSMutableArray *audioLayers = [NSMutableArray array];
[self.videoItem.audios enumerateObjectsUsingBlock:^(SVGAAudioEntity * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
SVGAAudioLayer *audioLayer = [[SVGAAudioLayer alloc] initWithAudioItem:obj videoItem:self.videoItem];
[audioLayers addObject:audioLayer];
}];
self.audioLayers = audioLayers;
[self update];
[self resize];
}
@@ -239,6 +258,17 @@
}
}
[CATransaction setDisableActions:NO];
if (self.forwardAnimating && self.audioLayers.count > 0) {
for (SVGAAudioLayer *layer in self.audioLayers) {
if (layer.audioItem.startFrame == self.currentFrame) {
[layer.audioPlayer setCurrentTime:(NSTimeInterval)(layer.audioItem.startTime / 1000)];
[layer.audioPlayer play];
}
else if (layer.audioItem.endFrame <= self.currentFrame) {
[layer.audioPlayer stop];
}
}
}
}
- (void)next {
@@ -253,6 +283,7 @@
self.currentFrame++;
if (self.currentFrame >= MIN(self.videoItem.frames, self.currentRange.location + self.currentRange.length)) {
self.currentFrame = MAX(0, self.currentRange.location);
[self clearAudios];
self.loopCount++;
}
}

View File

@@ -9,7 +9,7 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class SVGAVideoEntity, SVGAVideoSpriteEntity, SVGAVideoSpriteFrameEntity, SVGABitmapLayer, SVGAVectorLayer;
@class SVGAVideoEntity, SVGAVideoSpriteEntity, SVGAVideoSpriteFrameEntity, SVGABitmapLayer, SVGAVectorLayer, SVGAAudioEntity;
@class SVGAProtoMovieEntity;
@interface SVGAVideoEntity : NSObject
@@ -18,7 +18,9 @@
@property (nonatomic, readonly) int FPS;
@property (nonatomic, readonly) int frames;
@property (nonatomic, readonly) NSDictionary<NSString *, UIImage *> *images;
@property (nonatomic, readonly) NSDictionary<NSString *, NSData *> *audiosData;
@property (nonatomic, readonly) NSArray<SVGAVideoSpriteEntity *> *sprites;
@property (nonatomic, readonly) NSArray<SVGAAudioEntity *> *audios;
- (instancetype)initWithJSONObject:(NSDictionary *)JSONObject cacheDir:(NSString *)cacheDir;
- (void)resetImagesWithJSONObject:(NSDictionary *)JSONObject;
@@ -27,6 +29,7 @@
- (instancetype)initWithProtoObject:(SVGAProtoMovieEntity *)protoObject cacheDir:(NSString *)cacheDir;
- (void)resetImagesWithProtoObject:(SVGAProtoMovieEntity *)protoObject;
- (void)resetSpritesWithProtoObject:(SVGAProtoMovieEntity *)protoObject;
- (void)resetAudiosWithProtoObject:(SVGAProtoMovieEntity *)protoObject;
+ (SVGAVideoEntity *)readCache:(NSString *)cacheKey;
- (void)saveCache:(NSString *)cacheKey;

View File

@@ -6,9 +6,11 @@
// Copyright © 2016 UED Center. All rights reserved.
//
#import <AVFoundation/AVFoundation.h>
#import "SVGAVideoEntity.h"
#import "SVGABezierPath.h"
#import "SVGAVideoSpriteEntity.h"
#import "SVGAAudioEntity.h"
#import "Svga.pbobjc.h"
@interface SVGAVideoEntity ()
@@ -17,7 +19,9 @@
@property (nonatomic, assign) int FPS;
@property (nonatomic, assign) int frames;
@property (nonatomic, copy) NSDictionary<NSString *, UIImage *> *images;
@property (nonatomic, copy) NSDictionary<NSString *, NSData *> *audiosData;
@property (nonatomic, copy) NSArray<SVGAVideoSpriteEntity *> *sprites;
@property (nonatomic, copy) NSArray<SVGAAudioEntity *> *audios;
@property (nonatomic, copy) NSString *cacheDir;
@end
@@ -129,6 +133,7 @@ static NSCache *videoCache;
- (void)resetImagesWithProtoObject:(SVGAProtoMovieEntity *)protoObject {
NSMutableDictionary<NSString *, UIImage *> *images = [[NSMutableDictionary alloc] init];
NSMutableDictionary<NSString *, NSData *> *audiosData = [[NSMutableDictionary alloc] init];
NSDictionary *protoImages = [protoObject.images copy];
for (NSString *key in protoImages) {
NSString *fileName = [[NSString alloc] initWithData:protoImages[key] encoding:NSUTF8StringEncoding];
@@ -147,14 +152,22 @@ static NSCache *videoCache;
}
}
}
else {
UIImage *image = [[UIImage alloc] initWithData:protoImages[key] scale:2.0];
if (image != nil) {
[images setObject:image forKey:key];
else if ([protoImages[key] isKindOfClass:[NSData class]]) {
NSData *fileTag = [protoImages[key] subdataWithRange:NSMakeRange(0, 4)];
if (![[fileTag description] isEqualToString:@"<89504e47>"]) {
// mp3
[audiosData setObject:protoImages[key] forKey:key];
}
else {
UIImage *image = [[UIImage alloc] initWithData:protoImages[key] scale:2.0];
if (image != nil) {
[images setObject:image forKey:key];
}
}
}
}
self.images = images;
self.audiosData = audiosData;
}
- (void)resetSpritesWithProtoObject:(SVGAProtoMovieEntity *)protoObject {
@@ -168,6 +181,18 @@ static NSCache *videoCache;
}];
self.sprites = sprites;
}
- (void)resetAudiosWithProtoObject:(SVGAProtoMovieEntity *)protoObject {
NSMutableArray<SVGAAudioEntity *> *audios = [[NSMutableArray alloc] init];
NSArray *protoAudios = [protoObject.audiosArray copy];
[protoAudios enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj isKindOfClass:[SVGAProtoAudioEntity class]]) {
SVGAAudioEntity *audioItem = [[SVGAAudioEntity alloc] initWithProtoObject:obj];
[audios addObject:audioItem];
}
}];
self.audios = audios;
}
+ (SVGAVideoEntity *)readCache:(NSString *)cacheKey {
return [videoCache objectForKey:cacheKey];

View File

@@ -27,6 +27,7 @@
CF_EXTERN_C_BEGIN
@class SVGAProtoAudioEntity;
@class SVGAProtoFrameEntity;
@class SVGAProtoLayout;
@class SVGAProtoMovieParams;
@@ -174,6 +175,31 @@ typedef GPB_ENUM(SVGAProtoSpriteEntity_FieldNumber) {
@end
#pragma mark - SVGAProtoAudioEntity
typedef GPB_ENUM(SVGAProtoAudioEntity_FieldNumber) {
SVGAProtoAudioEntity_FieldNumber_AudioKey = 1,
SVGAProtoAudioEntity_FieldNumber_StartFrame = 2,
SVGAProtoAudioEntity_FieldNumber_EndFrame = 3,
SVGAProtoAudioEntity_FieldNumber_StartTime = 4,
};
@interface SVGAProtoAudioEntity : GPBMessage
/** 音频文件名 */
@property(nonatomic, readwrite, copy, null_resettable) NSString *audioKey;
/** 音频播放起始帧 */
@property(nonatomic, readwrite) int32_t startFrame;
/** 音频播放结束帧 */
@property(nonatomic, readwrite) int32_t endFrame;
/** 音频播放起始时间(相对音频长度) */
@property(nonatomic, readwrite) int32_t startTime;
@end
#pragma mark - SVGAProtoLayout
typedef GPB_ENUM(SVGAProtoLayout_FieldNumber) {
@@ -481,6 +507,7 @@ typedef GPB_ENUM(SVGAProtoMovieEntity_FieldNumber) {
SVGAProtoMovieEntity_FieldNumber_Params = 2,
SVGAProtoMovieEntity_FieldNumber_Images = 3,
SVGAProtoMovieEntity_FieldNumber_SpritesArray = 4,
SVGAProtoMovieEntity_FieldNumber_AudiosArray = 5,
};
@interface SVGAProtoMovieEntity : GPBMessage
@@ -503,6 +530,11 @@ typedef GPB_ENUM(SVGAProtoMovieEntity_FieldNumber) {
/** The number of items in @c spritesArray without causing the array to be created. */
@property(nonatomic, readonly) NSUInteger spritesArray_Count;
/** 音频列表 */
@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<SVGAProtoAudioEntity*> *audiosArray;
/** The number of items in @c audiosArray without causing the array to be created. */
@property(nonatomic, readonly) NSUInteger audiosArray_Count;
@end
NS_ASSUME_NONNULL_END

View File

@@ -13,7 +13,9 @@
#import "GPBProtocolBuffers_RuntimeSupport.h"
#endif
#import "Svga.pbobjc.h"
#import <stdatomic.h>
#import "Svga.pbobjc.h"
// @@protoc_insertion_point(imports)
#pragma clang diagnostic push
@@ -184,6 +186,87 @@ typedef struct SVGAProtoSpriteEntity__storage_ {
@end
#pragma mark - SVGAProtoAudioEntity
@implementation SVGAProtoAudioEntity
@dynamic audioKey;
@dynamic startFrame;
@dynamic endFrame;
@dynamic startTime;
typedef struct SVGAProtoAudioEntity__storage_ {
uint32_t _has_storage_[1];
int32_t startFrame;
int32_t endFrame;
int32_t startTime;
NSString *audioKey;
} SVGAProtoAudioEntity__storage_;
// This method is threadsafe because it is initially called
// in +initialize for each subclass.
+ (GPBDescriptor *)descriptor {
static GPBDescriptor *descriptor = nil;
if (!descriptor) {
static GPBMessageFieldDescription fields[] = {
{
.name = "audioKey",
.dataTypeSpecific.className = NULL,
.number = SVGAProtoAudioEntity_FieldNumber_AudioKey,
.hasIndex = 0,
.offset = (uint32_t)offsetof(SVGAProtoAudioEntity__storage_, audioKey),
.flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom),
.dataType = GPBDataTypeString,
},
{
.name = "startFrame",
.dataTypeSpecific.className = NULL,
.number = SVGAProtoAudioEntity_FieldNumber_StartFrame,
.hasIndex = 1,
.offset = (uint32_t)offsetof(SVGAProtoAudioEntity__storage_, startFrame),
.flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom),
.dataType = GPBDataTypeInt32,
},
{
.name = "endFrame",
.dataTypeSpecific.className = NULL,
.number = SVGAProtoAudioEntity_FieldNumber_EndFrame,
.hasIndex = 2,
.offset = (uint32_t)offsetof(SVGAProtoAudioEntity__storage_, endFrame),
.flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom),
.dataType = GPBDataTypeInt32,
},
{
.name = "startTime",
.dataTypeSpecific.className = NULL,
.number = SVGAProtoAudioEntity_FieldNumber_StartTime,
.hasIndex = 3,
.offset = (uint32_t)offsetof(SVGAProtoAudioEntity__storage_, startTime),
.flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom),
.dataType = GPBDataTypeInt32,
},
};
GPBDescriptor *localDescriptor =
[GPBDescriptor allocDescriptorForClass:[SVGAProtoAudioEntity class]
rootClass:[SVGAProtoSvgaRoot class]
file:SVGAProtoSvgaRoot_FileDescriptor()
fields:fields
fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription))
storageSize:sizeof(SVGAProtoAudioEntity__storage_)
flags:GPBDescriptorInitializationFlag_None];
#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
static const char *extraTextFormatInfo =
"\004\001\010\000\002\n\000\003\010\000\004\t\000";
[localDescriptor setupExtraTextInfo:extraTextFormatInfo];
#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
NSAssert(descriptor == nil, @"Startup recursed!");
descriptor = localDescriptor;
}
return descriptor;
}
@end
#pragma mark - SVGAProtoLayout
@implementation SVGAProtoLayout
@@ -483,7 +566,7 @@ void SVGAProtoShapeEntity_ClearArgsOneOfCase(SVGAProtoShapeEntity *message) {
#pragma mark - Enum SVGAProtoShapeEntity_ShapeType
GPBEnumDescriptor *SVGAProtoShapeEntity_ShapeType_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
static _Atomic(GPBEnumDescriptor*) descriptor = nil;
if (!descriptor) {
static const char *valueNames =
"Shape\000Rect\000Ellipse\000Keep\000";
@@ -499,7 +582,8 @@ GPBEnumDescriptor *SVGAProtoShapeEntity_ShapeType_EnumDescriptor(void) {
values:values
count:(uint32_t)(sizeof(values) / sizeof(int32_t))
enumVerifier:SVGAProtoShapeEntity_ShapeType_IsValidValue];
if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
GPBEnumDescriptor *expected = nil;
if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {
[worker release];
}
}
@@ -901,7 +985,7 @@ void SetSVGAProtoShapeEntity_ShapeStyle_LineJoin_RawValue(SVGAProtoShapeEntity_S
#pragma mark - Enum SVGAProtoShapeEntity_ShapeStyle_LineCap
GPBEnumDescriptor *SVGAProtoShapeEntity_ShapeStyle_LineCap_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
static _Atomic(GPBEnumDescriptor*) descriptor = nil;
if (!descriptor) {
static const char *valueNames =
"LineCapButt\000LineCapRound\000LineCapSquare\000";
@@ -918,7 +1002,8 @@ GPBEnumDescriptor *SVGAProtoShapeEntity_ShapeStyle_LineCap_EnumDescriptor(void)
count:(uint32_t)(sizeof(values) / sizeof(int32_t))
enumVerifier:SVGAProtoShapeEntity_ShapeStyle_LineCap_IsValidValue
extraTextFormatInfo:extraTextFormatInfo];
if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
GPBEnumDescriptor *expected = nil;
if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {
[worker release];
}
}
@@ -939,7 +1024,7 @@ BOOL SVGAProtoShapeEntity_ShapeStyle_LineCap_IsValidValue(int32_t value__) {
#pragma mark - Enum SVGAProtoShapeEntity_ShapeStyle_LineJoin
GPBEnumDescriptor *SVGAProtoShapeEntity_ShapeStyle_LineJoin_EnumDescriptor(void) {
static GPBEnumDescriptor *descriptor = NULL;
static _Atomic(GPBEnumDescriptor*) descriptor = nil;
if (!descriptor) {
static const char *valueNames =
"LineJoinMiter\000LineJoinRound\000LineJoinBeve"
@@ -957,7 +1042,8 @@ GPBEnumDescriptor *SVGAProtoShapeEntity_ShapeStyle_LineJoin_EnumDescriptor(void)
count:(uint32_t)(sizeof(values) / sizeof(int32_t))
enumVerifier:SVGAProtoShapeEntity_ShapeStyle_LineJoin_IsValidValue
extraTextFormatInfo:extraTextFormatInfo];
if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) {
GPBEnumDescriptor *expected = nil;
if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {
[worker release];
}
}
@@ -1152,6 +1238,7 @@ typedef struct SVGAProtoFrameEntity__storage_ {
@dynamic hasParams, params;
@dynamic images, images_Count;
@dynamic spritesArray, spritesArray_Count;
@dynamic audiosArray, audiosArray_Count;
typedef struct SVGAProtoMovieEntity__storage_ {
uint32_t _has_storage_[1];
@@ -1159,6 +1246,7 @@ typedef struct SVGAProtoMovieEntity__storage_ {
SVGAProtoMovieParams *params;
NSMutableDictionary *images;
NSMutableArray *spritesArray;
NSMutableArray *audiosArray;
} SVGAProtoMovieEntity__storage_;
// This method is threadsafe because it is initially called
@@ -1203,6 +1291,15 @@ typedef struct SVGAProtoMovieEntity__storage_ {
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
},
{
.name = "audiosArray",
.dataTypeSpecific.className = GPBStringifySymbol(SVGAProtoAudioEntity),
.number = SVGAProtoMovieEntity_FieldNumber_AudiosArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(SVGAProtoMovieEntity__storage_, audiosArray),
.flags = GPBFieldRepeated,
.dataType = GPBDataTypeMessage,
},
};
GPBDescriptor *localDescriptor =
[GPBDescriptor allocDescriptorForClass:[SVGAProtoMovieEntity class]