Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/divideMovieViewController/XspfQTPlayerMovieMode.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 390 - (show annotations) (download)
Tue Jul 2 14:11:00 2013 UTC (10 years, 9 months ago) by masakih
File size: 7421 byte(s)
[New] 動画の連結中にそれを示す動画を再生
1 //
2 // XspfQTPlayerMovieMode.m
3 // XspfQT
4 //
5 // Created by Hori,Masaki on 2013/06/25.
6 // Copyright (c) 2013å¹´ masakih. All rights reserved.
7 //
8
9 #import "XspfQTPlayerMovieMode.h"
10
11
12 #import <QTKit/QTKit.h>
13
14 #import "HMXSPFComponent.h"
15 #import "NSURL-HMExtensions.h"
16 #import "XspfQTMovieLoader.h"
17 #import "XspfQTMovieTimer.h"
18 #import "XspfQTPreference.h"
19
20
21 static NSString *XspfQTCurrentTrackKey = @"currentTrack";
22
23 static NSString *joinTheMovies = @"JoinTheMovies";
24 static NSString *joinTheMoviesExt = @"m4v";
25
26 static QTMovie *joinTheMoviesMovie = nil;
27
28
29 @interface XspfQTPlayerMovieMode ()
30
31 @property (retain) XspfQTMovieLoader *loader;
32 @property BOOL didJoin;
33
34 @end
35
36 @implementation XspfQTPlayerMovieMode
37 @synthesize loader = _loader;
38 @synthesize didJoin = _didJoin;
39
40
41 static XspfQTMovieTimer* timer = nil;
42 + (void)initialize
43 {
44 static BOOL isFirst = YES;
45 if(isFirst) {
46 isFirst = NO;
47 timer = [[XspfQTMovieTimer movieTimerWithFireInterval:0.5] retain];
48 }
49 }
50
51 - (id)init
52 {
53 self = [super init];
54 if(self) {
55 _loader = [[XspfQTMovieLoader loaderWithMovieURL:nil] retain];
56 [timer put:self];
57 }
58
59 return self;
60 }
61
62 - (void)dealloc
63 {
64 [_loader release];
65 [timer remove:self];
66
67 [[_playlist childAtIndex:0] removeObserver:self forKeyPath:XspfQTCurrentTrackKey];
68 [_playlist release];
69
70 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
71 [nc removeObserver:self];
72 [_playingMovie release];
73
74 [durations release];
75
76 [super dealloc];
77 }
78
79 - (QTMovie *)joinTheMoviesMovie
80 {
81 if(joinTheMoviesMovie) return joinTheMoviesMovie;
82
83 NSString *path = [[NSBundle mainBundle] pathForResource:joinTheMovies ofType:joinTheMoviesExt];
84
85 NSError *error = nil;
86 joinTheMoviesMovie = [[QTMovie alloc] initWithFile:path error:&error];
87 [joinTheMoviesMovie setAttribute:[NSNumber numberWithBool:YES] forKey:QTMovieLoopsAttribute];
88
89 // for do not update time indicator.
90 [joinTheMoviesMovie setAttribute:@"JoinTheMovie" forKey:QTMovieDisplayNameAttribute];
91
92 return joinTheMoviesMovie;
93 }
94
95 - (void)setPlaylist:(HMXSPFComponent *)newList
96 {
97 if(_playlist == newList) return;
98
99 [[_playlist childAtIndex:0] removeObserver:self forKeyPath:XspfQTCurrentTrackKey];
100 [_playlist autorelease];
101 _playlist = [newList retain];
102 [[_playlist childAtIndex:0] addObserver:self
103 forKeyPath:XspfQTCurrentTrackKey
104 options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
105 context:NULL];
106
107 if(!newList) {
108 [timer remove:self];
109 }
110 }
111 - (HMXSPFComponent *)playlist
112 {
113 return _playlist;
114 }
115
116 - (HMXSPFComponent *)trackList
117 {
118 return [self.playlist childAtIndex:0];
119 }
120
121 + (NSSet *)keyPathsForValuesAffectingPlayingMovieDuration
122 {
123 return [NSSet setWithObject:@"playingMovie"];
124 }
125 - (void)setPlayingMovie:(QTMovie *)newMovie
126 {
127 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
128 if(_playingMovie) {
129 [nc removeObserver:self
130 name:nil
131 object:_playingMovie];
132 }
133
134 [_playingMovie autorelease];
135 _playingMovie = [newMovie retain];
136 self.playingMovieDuration = 0;
137
138 if(_playingMovie) {
139 [nc addObserver:self
140 selector:@selector(notifee:)
141 name:QTMovieRateDidChangeNotification
142 object:_playingMovie];
143 }
144 }
145 - (QTMovie *)playingMovie
146 {
147 return _playingMovie;
148 }
149 - (void)setPlayingMovieDuration:(NSTimeInterval)playingMovieDuration
150 {
151 _playingMovieDuration = playingMovieDuration;
152 }
153 - (NSTimeInterval)playingMovieDuration
154 {
155 if(_playingMovieDuration == 0) {
156 QTTime qttime = [self.playingMovie duration];
157 if(!QTGetTimeInterval(qttime, &_playingMovieDuration)) _playingMovieDuration = 0;
158 }
159
160 return _playingMovieDuration;
161 }
162
163 - (void)buildStartPositionsWithDurations:(NSArray *)aDurations
164 {
165 QTTime time = QTZeroTime;
166 NSMutableArray *aStartPoints = [NSMutableArray array];
167 [aStartPoints addObject:[NSValue valueWithQTTime:time]];
168
169 for(id value in aDurations) {
170 QTTime aTime = [value QTTimeValue];
171 time = QTTimeIncrement(time, aTime);
172 [aStartPoints addObject:[NSValue valueWithQTTime:time]];
173 }
174 durations = [[NSArray alloc] initWithArray:aStartPoints];
175 }
176 - (void)joinMovie
177 {
178 dispatch_queue_t queue = dispatch_queue_create("join movies", 0);
179 dispatch_async(queue, ^() {
180 QTMovie *theMovie = [QTMovie movie];
181 [theMovie setMovieAttributes:@{QTMovieEditableAttribute:@YES}];
182
183 HMXSPFComponent *trackList = self.trackList;
184
185 NSMutableArray *aDurations = [NSMutableArray array];
186
187 NSArray *children = [trackList children];
188 BOOL firstTime = YES;
189 for(HMXSPFComponent *track in children) {
190 self.loader.movieURL = [track movieLocation];
191 [self.loader load];
192 QTMovie *aMovie = self.loader.qtMovie;
193
194 QTTime qttime = [aMovie duration];
195 [aDurations addObject:[NSValue valueWithQTTime:qttime]];
196 id t = [NSValueTransformer valueTransformerForName:@"XspfQTTimeDateTransformer"];
197 [track setCurrentTrackDuration:[t transformedValue:[NSValue valueWithQTTime:qttime]]];
198
199 QTTimeRange aMovieRange = QTMakeTimeRange(QTZeroTime, [aMovie duration]);
200 if(firstTime) {
201 [aMovie setSelection:aMovieRange];
202 [theMovie appendSelectionFromMovie:aMovie];
203 } else {
204 QTTime insertPoint = [theMovie duration];
205 insertPoint = QTTimeDecrement(insertPoint, QTMakeTimeWithTimeInterval(0.05));
206 [theMovie insertSegmentOfMovie:aMovie timeRange:aMovieRange atTime:insertPoint];
207 }
208 firstTime = NO;
209 }
210
211 [self buildStartPositionsWithDurations:aDurations];
212
213 dispatch_async(dispatch_get_main_queue(), ^(void){
214 self.playingMovie = theMovie;
215 });
216 });
217 }
218
219 - (void)moveToStartPointNuber:(id)number
220 {
221 NSUInteger index = [[self.trackList children] indexOfObject:number];
222 QTTime time = [[durations objectAtIndex:index] QTTimeValue];
223 [self.playingMovie setCurrentTime:time];
224 }
225 - (void)observeValueForKeyPath:(NSString *)keyPath
226 ofObject:(id)object
227 change:(NSDictionary *)change
228 context:(void *)context
229 {
230 if([keyPath isEqualToString:XspfQTCurrentTrackKey]) {
231 if(self.didJoin) {
232 if(ignoreChangeTrackEvent) return;
233 id number = [change objectForKey:NSKeyValueChangeNewKey];
234 [self moveToStartPointNuber:number];
235 [self.playingMovie play];
236 } else {
237 self.didJoin = YES;
238 self.playingMovie = [self joinTheMoviesMovie];
239 [self.playingMovie play];
240 [self joinMovie];
241 }
242 }
243 }
244
245
246 - (void)notifee:(id)notification
247 {
248 HMXSPFComponent *track = self.trackList.currentTrack;
249 NSNumber *rateValue = [[notification userInfo] objectForKey:QTMovieRateDidChangeNotificationParameter];
250 if(rateValue) {
251 float rate = [rateValue floatValue];
252 if(rate == 0) {
253 track.isPlayed = NO;
254 [timer suspend:self];
255 } else {
256 track.isPlayed = YES;
257 [timer resume:self];
258 }
259 }
260 }
261
262 // call from XspfQTMovieTimer.
263 - (void)fire
264 {
265 // �在�durationを�得
266 QTTime duration = [self.playingMovie currentTime];
267
268 // �択トラックを�得
269 HMXSPFComponent *currentTrack = self.trackList.currentTrack;
270
271 // �択トラック��生中�?
272 // duration���トラックを�得
273 NSUInteger index = [self.trackList indexOfChild:currentTrack];
274 NSUInteger playingIndex = NSNotFound;
275
276 NSUInteger i = 0;
277 for(id time in durations) {
278 QTTime qtTime = [time QTTimeValue];
279 if(QTTimeCompare(qtTime, duration) == NSOrderedDescending) {
280 playingIndex = i - 1;
281 break;
282 }
283 i++;
284 }
285 // �生中�らreturn
286 if(index == playingIndex) return;
287
288 // �生中トラックを�択
289 ignoreChangeTrackEvent = YES;
290 self.trackList.selectionIndex = playingIndex;
291 ignoreChangeTrackEvent = NO;
292 }
293 @end

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26