Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTDocument.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 207 - (hide annotations) (download)
Sun Mar 29 13:40:44 2009 UTC (15 years ago) by masaki
File size: 10946 byte(s)
[Refactoring]文字列定数を静的変数にした。
1 masaki 2 //
2 masaki 72 // XspfQTDocument.m
3 masaki 2 // XspfQT
4     //
5     // Created by Hori,Masaki on 08/08/29.
6     // Copyright masakih 2008 . All rights reserved.
7     //
8    
9 masaki 72 #import "XspfQTDocument.h"
10 masaki 202 #import "XspfQTAppDelegate.h"
11 masaki 205 #import "XspfQTPreference.h"
12 masaki 72 #import "XspfQTComponent.h"
13     #import "XspfQTMovieWindowController.h"
14     #import "XspfQTPlayListWindowController.h"
15 masaki 171 #import <QTKit/QTKit.h>
16 masaki 2
17 masaki 181 #import "NSURL-XspfQT-Extensions.h"
18     #import "XspfQTMovieLoader.h"
19    
20 masaki 207
21     #pragma mark #### Global Variables ####
22     /********* Global variables *******/
23     NSString *XspfQTDocumentWillCloseNotification = @"XspfQTDocumentWillCloseNotification";
24    
25     /**********************************/
26    
27 masaki 72 @interface XspfQTDocument (Private)
28 masaki 116 - (void)setPlaylist:(XspfQTComponent *)newList;
29     - (XspfQTComponent *)playlist;
30 masaki 31 - (NSXMLDocument *)XMLDocument;
31     - (NSData *)outputData;
32 masaki 173 - (void)setPlayingMovie:(QTMovie *)newMovie;
33 masaki 141 - (NSData *)dataFromURL:(NSURL *)url error:(NSError **)outError;
34 masaki 2 @end
35    
36 masaki 207 static NSString *XspfDocumentType = @"XML Shareable Playlist Format";
37     static NSString *QuickTimeMovieDocumentType = @"QuickTime Movie";
38     static NSString *MatroskaVideoDocumentType = @"Matroska Video";
39     static NSString *DivXMediaFormatDocumentType = @"DivX Media Format";
40    
41 masaki 72 @implementation XspfQTDocument
42 masaki 2
43 masaki 182 - (id)init
44     {
45     self = [super init];
46     if(self) {
47     loader = [[XspfQTMovieLoader loaderWithMovieURL:nil delegate:nil] retain];
48    
49 masaki 197 // NSLog(@"Enable preloading.");
50     preloadingTimer = [NSTimer scheduledTimerWithTimeInterval:10
51     target:self
52     selector:@selector(checkPreload:)
53     userInfo:nil
54     repeats:YES];
55 masaki 182 // NSLog(@"init was called");
56     }
57    
58     return self;
59     }
60 masaki 95 - (id)initWithType:(NSString *)typeName error:(NSError **)outError
61     {
62     [self init];
63    
64 masaki 116 id newPlaylist = [XspfQTComponent xspfPlaylist];
65     if(!newPlaylist) {
66 masaki 95 [self autorelease];
67     return nil;
68     }
69    
70 masaki 116 [self setPlaylist:newPlaylist];
71 masaki 121 // NSLog(@"new playlist is (%@)%@", NSStringFromClass([[self playlist] class]), [self playlist]);
72 masaki 95
73     return self;
74     }
75 masaki 182 - (void)dealloc
76     {
77     [self setPlayingMovie:nil];
78     [self setPlaylist:nil];
79     [playListWindowController release];
80     [movieWindowController release];
81     [loader release];
82    
83     [super dealloc];
84     }
85 masaki 2
86     - (void)makeWindowControllers
87     {
88 masaki 72 playListWindowController = [[XspfQTPlayListWindowController alloc] init];
89 masaki 2 [self addWindowController:playListWindowController];
90    
91 masaki 72 movieWindowController = [[XspfQTMovieWindowController alloc] init];
92 masaki 42 [movieWindowController setShouldCloseDocument:YES];
93 masaki 2 [self addWindowController:movieWindowController];
94     }
95    
96     - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
97     {
98 masaki 31 return [self outputData];
99 masaki 2 }
100    
101 masaki 141 - (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
102     {
103     *outError = nil;
104    
105 masaki 207 if(![typeName isEqualToString:QuickTimeMovieDocumentType]
106     && ![typeName isEqualToString:MatroskaVideoDocumentType]
107     && ![typeName isEqualToString:DivXMediaFormatDocumentType]) {
108 masaki 141 NSData *data = [self dataFromURL:absoluteURL error:outError];
109     if(!data) return NO;
110    
111     return [self readFromData:data ofType:typeName error:outError];
112     }
113    
114     NSString *xmlElem;
115     xmlElem = [NSString stringWithFormat:@"<track><location>%@</location></track>",
116     [absoluteURL absoluteString]];
117    
118     NSError *error = nil;
119     id new = [XspfQTComponent xspfComponentWithXMLElementString:xmlElem
120     error:&error];
121     if(error) {
122     NSLog(@"%@", error);
123     if(outError) {
124     *outError = error;
125     }
126     return NO;
127     }
128    
129     id pl = [XspfQTComponent xspfPlaylist];
130     if(!pl) {
131     return NO;
132     }
133    
134     [[[pl children] objectAtIndex:0] addChild:new];
135    
136     [self setPlaylist:pl];
137     id t = [self trackList];
138     if(![t title]) {
139     [t setTitle:[[[self fileURL] path] lastPathComponent]];
140     }
141    
142 masaki 207 [self setFileType:XspfDocumentType];
143 masaki 141 [self setFileURL:nil];
144    
145     return YES;
146     }
147 masaki 2 - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
148     {
149 masaki 141 *outError = nil;
150    
151 masaki 207 if(![typeName isEqualToString:XspfDocumentType]) {
152 masaki 141 return NO;
153     }
154    
155 masaki 2 NSError *error = nil;
156 masaki 10 NSXMLDocument *d = [[[NSXMLDocument alloc] initWithData:data
157     options:0
158     error:&error] autorelease];
159 masaki 121 if(error) {
160     NSLog(@"%@", error);
161     *outError = error;
162     return NO;
163     }
164 masaki 2 NSXMLElement *root = [d rootElement];
165 masaki 116 id pl = [XspfQTComponent xspfComponemtWithXMLElement:root];
166 masaki 121 if(!pl) {
167     NSLog(@"Can not create XspfQTComponent.");
168     return NO;
169     }
170 masaki 116 [self setPlaylist:pl];
171 masaki 2
172 masaki 116 id t = [self trackList];
173 masaki 39 if(![t title]) {
174 masaki 165 [t setTitle:[[[[self fileURL] path] lastPathComponent] stringByDeletingPathExtension]];
175 masaki 39 }
176 masaki 2
177 masaki 121 // NSLog(@"open playlist is (%@)%@", NSStringFromClass([[self playlist] class]), [self playlist]);
178    
179 masaki 2 return YES;
180     }
181    
182 masaki 42 - (void)close
183     {
184 masaki 61 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
185 masaki 72 [nc postNotificationName:XspfQTDocumentWillCloseNotification object:self];
186 masaki 61
187 masaki 42 [self removeWindowController:playListWindowController];
188     [playListWindowController release];
189     playListWindowController = nil;
190    
191     [self removeWindowController:movieWindowController];
192     [movieWindowController release];
193     movieWindowController = nil;
194    
195 masaki 189 [preloadingTimer invalidate];
196    
197 masaki 42 [super close];
198     }
199    
200 masaki 33 - (IBAction)togglePlayAndPause:(id)sender
201     {
202     [movieWindowController togglePlayAndPause:sender];
203     }
204 masaki 2 - (IBAction)showPlayList:(id)sender
205     {
206     [playListWindowController showWindow:self];
207     }
208    
209 masaki 116 - (void)setPlaylist:(XspfQTComponent *)newList
210 masaki 2 {
211 masaki 116 if(playlist == newList) return;
212 masaki 2
213 masaki 171 [[playlist childAtIndex:0] removeObserver:self forKeyPath:@"currentTrack"];
214 masaki 116 [playlist autorelease];
215     playlist = [newList retain];
216 masaki 171 [[playlist childAtIndex:0] addObserver:self
217     forKeyPath:@"currentTrack"
218     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
219     context:NULL];
220 masaki 2 }
221 masaki 116 - (XspfQTComponent *)playlist
222     {
223     return playlist;
224     }
225    
226 masaki 72 - (XspfQTComponent *)trackList
227 masaki 2 {
228 masaki 116 return [playlist childAtIndex:0];
229 masaki 2 }
230    
231 masaki 196 + (NSSet *)keyPathsForValuesAffectingPlayingMovieDuration
232     {
233     return [NSSet setWithObject:@"playingMovie"];
234     }
235 masaki 171 - (void)setPlayingMovie:(QTMovie *)newMovie
236     {
237     // NSLog(@"new movie is %@!!", newMovie);
238     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
239 masaki 193 if(playingMovie) {
240 masaki 188 [nc removeObserver:self
241     name:nil
242     object:playingMovie];
243     }
244 masaki 171
245     [playingMovie autorelease];
246 masaki 181 playingMovie = [newMovie retain];
247 masaki 196 playingMovieDuration = 0;
248 masaki 171
249 masaki 193 if(playingMovie) {
250 masaki 188 [nc addObserver:self
251     selector:@selector(notifee:)
252     name:QTMovieRateDidChangeNotification
253     object:playingMovie];
254     }
255 masaki 171 }
256     - (QTMovie *)playingMovie
257     {
258     // NSLog(@"%@ is called!!", NSStringFromSelector(_cmd));
259     return playingMovie;
260     }
261 masaki 182 - (NSTimeInterval)playingMovieDuration
262     {
263     if(playingMovieDuration == 0) {
264     QTTime qttime = [[self playingMovie] duration];
265     if(!QTGetTimeInterval(qttime, &playingMovieDuration)) playingMovieDuration = 0;
266     }
267    
268     return playingMovieDuration;
269     }
270 masaki 171 - (void)loadMovie
271     {
272     NSURL *location = [[self trackList] movieLocation];
273    
274 masaki 174 if(playingMovie) {
275     id movieURL = [playingMovie attributeForKey:QTMovieURLAttribute];
276 masaki 181 if([location isEqualUsingLocalhost:movieURL]) return;
277 masaki 174 }
278    
279 masaki 182 [loader setMovieURL:location];
280 masaki 181 [loader load];
281     QTMovie *newMovie = [loader qtMovie];
282     [self setPlayingMovie:newMovie];
283 masaki 171
284     QTTime qttime = [newMovie duration];
285     id t = [NSValueTransformer valueTransformerForName:@"XspfQTTimeDateTransformer"];
286     [[self trackList] setCurrentTrackDuration:[t transformedValue:[NSValue valueWithQTTime:qttime]]];
287 masaki 182
288     didPreloading = NO;
289 masaki 171 }
290 masaki 158 - (void)setPlayingTrackIndex:(unsigned)index
291 masaki 2 {
292 masaki 181 // [self performSelector:@selector(loadMovie) withObject:nil afterDelay:0.0];
293     [self loadMovie];
294 masaki 2 }
295 masaki 171 - (void)observeValueForKeyPath:(NSString *)keyPath
296     ofObject:(id)object
297     change:(NSDictionary *)change
298     context:(void *)context
299     {
300     if([keyPath isEqualToString:@"currentTrack"]) {
301     id trackList = [self trackList];
302     unsigned index = [trackList selectionIndex];
303     [self setPlayingTrackIndex:index];
304     }
305     }
306 masaki 31
307     - (NSData *)outputData
308     {
309     return [[self XMLDocument] XMLDataWithOptions:NSXMLNodePrettyPrint];
310     }
311 masaki 71 - (NSXMLDocument *)XMLDocument
312 masaki 31 {
313 masaki 116 id root = [[self playlist] XMLElement];
314 masaki 31
315     id d = [[[NSXMLDocument alloc] initWithRootElement:root] autorelease];
316     [d setVersion:@"1.0"];
317     [d setCharacterEncoding:@"UTF-8"];
318    
319     return d;
320     }
321 masaki 42
322 masaki 89 - (void)insertComponentFromURL:(NSURL *)url atIndex:(NSUInteger)index
323     {
324     NSString *xmlElem;
325     xmlElem = [NSString stringWithFormat:@"<track><location>%@</location></track>",
326     [url absoluteString]];
327    
328     NSError *error = nil;
329 masaki 117 id new = [XspfQTComponent xspfComponentWithXMLElementString:xmlElem
330     error:&error];
331 masaki 89 if(error) {
332     NSLog(@"%@", error);
333     @throw self;
334     }
335    
336     if(!new) {
337     @throw self;
338     }
339    
340     [self insertComponent:new atIndex:index];
341     }
342 masaki 86 - (void)insertComponent:(XspfQTComponent *)item atIndex:(NSUInteger)index
343 masaki 55 {
344 masaki 83 id undo = [self undoManager];
345 masaki 86 [undo registerUndoWithTarget:self selector:@selector(removeComponent:) object:item];
346 masaki 78 [[self trackList] insertChild:item atIndex:index];
347 masaki 55 }
348 masaki 86 - (void)removeComponent:(XspfQTComponent *)item
349 masaki 55 {
350 masaki 83 NSUInteger index = [[self trackList] indexOfChild:item];
351 masaki 121 if(index == NSNotFound) {
352     NSLog(@"Con not found item (%@)", item);
353     return;
354     }
355 masaki 83
356     id undo = [self undoManager];
357 masaki 86 [[undo prepareWithInvocationTarget:self] insertComponent:item atIndex:index];
358 masaki 55 [[self trackList] removeChild:item];
359     }
360    
361 masaki 141 - (NSData *)dataFromURL:(NSURL *)url error:(NSError **)outError
362     {
363     NSURLRequest *req = [NSURLRequest requestWithURL:url];
364     NSURLResponse *res = nil;
365     NSError *err = nil;
366     NSData *data = [NSURLConnection sendSynchronousRequest:req
367     returningResponse:&res
368     error:&err];
369     if(err) {
370     if(outError) {
371     *outError = err;
372     }
373     return nil;
374     }
375    
376     return data;
377     }
378    
379 masaki 171 - (void)notifee:(id)notification
380     {
381     // NSLog(@"Notifed: name -> (%@)\ndict -> (%@)", [notification name], [notification userInfo]);
382    
383     id track = [[self trackList] currentTrack];
384     NSNumber *rateValue = [[notification userInfo] objectForKey:QTMovieRateDidChangeNotificationParameter];
385     if(rateValue) {
386     float rate = [rateValue floatValue];
387     if(rate == 0) {
388     [track setIsPlayed:NO];
389     } else {
390     [track setIsPlayed:YES];
391     }
392     }
393     }
394    
395 masaki 182 - (void)checkPreload:(NSTimer *)timer
396     {
397 masaki 205 if(![XspfQTPref preloadingEnabled]) return;
398 masaki 182 if(didPreloading) return;
399    
400     NSTimeInterval duration;
401     NSTimeInterval current;
402     QTTime qttime = [playingMovie currentTime];
403     if(!QTGetTimeInterval(qttime, &current)) return;
404    
405     duration = [self playingMovieDuration];
406    
407 masaki 205 if( current / duration > [XspfQTPref beginingPreloadPercent] ) {
408 masaki 182 didPreloading = YES;
409     XspfQTComponent *list = [self trackList];
410     unsigned nextIndex = [list selectionIndex] + 1;
411     unsigned max = [list childrenCount];
412     if(max <= nextIndex) return;
413    
414     XspfQTComponent *nextTrack = [list childAtIndex:nextIndex];
415     NSURL *nextMovieURL = [nextTrack movieLocation];
416     [loader setMovieURL:nextMovieURL];
417     [loader load];
418    
419     // NSLog(@"Start preloading.");
420     }
421     }
422    
423 masaki 31 - (IBAction)dump:(id)sender
424     {
425     NSString *s = [[[NSString alloc] initWithData:[self outputData]
426     encoding:NSUTF8StringEncoding] autorelease];
427    
428     NSLog(@"%@", s);
429     }
430 masaki 2 @end
431    

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