Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/divideMovieViewController/XspfQTDocument.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 390 - (hide annotations) (download)
Tue Jul 2 14:11:00 2013 UTC (10 years, 9 months ago) by masakih
File size: 12783 byte(s)
[New] 動画の連結中にそれを示す動画を再生
1 masaki 2 //
2 masaki 72 // XspfQTDocument.m
3 masaki 2 // XspfQT
4     //
5     // Created by Hori,Masaki on 08/08/29.
6     //
7    
8 masakih 312 /*
9 masakih 316 This source code is release under the New BSD License.
10 masakih 370 Copyright (c) 2008-2010,2012, masakih
11 masakih 312 All rights reserved.
12    
13 masakih 316 ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満たす場合に
14     限り、再頒布および使用が許可されます。
15    
16     1, ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項を含
17     めること。
18     2, バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作権表
19     示、本条件一覧、および下記免責条項を含めること。
20     3, 書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進に、
21     コントリビューターの名前を使用してはならない。
22     本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、
23     明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証
24     も含め、またそれに限定されない、いかなる保証もありません。著作権者もコントリビューター
25     も、事由のいかんを問わず、 損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか
26     厳格責任であるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する
27     可能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品または代用
28     サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定
29     されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害につい
30     て、一切責任を負わないものとします。
31 masakih 312 -------------------------------------------------------------------
32 masakih 370 Copyright (c) 2008-2010,2012, masakih
33 masakih 312 All rights reserved.
34    
35 masakih 316 Redistribution and use in source and binary forms, with or without
36     modification, are permitted provided that the following conditions
37     are met:
38 masakih 312
39 masakih 316 1, Redistributions of source code must retain the above copyright
40     notice, this list of conditions and the following disclaimer.
41     2, Redistributions in binary form must reproduce the above copyright
42     notice, this list of conditions and the following disclaimer in
43     the documentation and/or other materials provided with the
44     distribution.
45     3, The names of its contributors may be used to endorse or promote
46     products derived from this software without specific prior
47     written permission.
48     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53     INCIDENTAL, SPECIAL,EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
54     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
56     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
58     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59     POSSIBILITY OF SUCH DAMAGE.
60 masakih 312 */
61    
62 masaki 72 #import "XspfQTDocument.h"
63 masaki 202 #import "XspfQTAppDelegate.h"
64 masaki 205 #import "XspfQTPreference.h"
65 masaki 306 #import "HMXSPFComponent.h"
66 masaki 72 #import "XspfQTMovieWindowController.h"
67     #import "XspfQTPlayListWindowController.h"
68 masaki 171 #import <QTKit/QTKit.h>
69 masaki 2
70 masaki 269 #import "XspfQTValueTransformers.h"
71 masaki 181
72 masakih 385 #import "XspfQTPlayer.h"
73 masakih 387 #import "XspfQTPlayerMovieMode.h"
74 masaki 207
75 masaki 298
76 masakih 385
77 masaki 207 #pragma mark #### Global Variables ####
78     /********* Global variables *******/
79     NSString *XspfQTDocumentWillCloseNotification = @"XspfQTDocumentWillCloseNotification";
80    
81     /**********************************/
82    
83 masakih 370 @interface XspfQTDocument()
84     @property (retain) HMXSPFComponent *playlist;
85     @property (readonly) NSXMLDocument *XMLDocument;
86    
87 masakih 385 @property (retain) XspfQTPlayer *player;
88    
89 masakih 370 @end
90    
91 masaki 72 @interface XspfQTDocument (Private)
92 masaki 141 - (NSData *)dataFromURL:(NSURL *)url error:(NSError **)outError;
93 masaki 274
94     inline static BOOL isXspfFileType(NSString *typeName);
95     inline static BOOL isReadableMovieType(NSString *typeName);
96 masaki 2 @end
97    
98 masaki 207 static NSString *XspfDocumentType = @"XML Shareable Playlist Format";
99     static NSString *QuickTimeMovieDocumentType = @"QuickTime Movie";
100     static NSString *MatroskaVideoDocumentType = @"Matroska Video";
101     static NSString *DivXMediaFormatDocumentType = @"DivX Media Format";
102    
103 masaki 224 static NSString *XspfUTI = @"com.masakih.xspf";
104    
105 masaki 72 @implementation XspfQTDocument
106 masaki 2
107 masakih 385 @synthesize player = _player;
108 masakih 370
109 masaki 298
110 masaki 182 - (id)init
111     {
112     self = [super init];
113     if(self) {
114 masakih 390 // _player = [[XspfQTPlayer alloc] init];
115 masakih 387 _player = [[XspfQTPlayerMovieMode alloc] init];
116 masaki 182 }
117    
118     return self;
119     }
120 masaki 95 - (id)initWithType:(NSString *)typeName error:(NSError **)outError
121     {
122     [self init];
123    
124 masaki 306 id newPlaylist = [HMXSPFComponent xspfPlaylist];
125 masaki 116 if(!newPlaylist) {
126 masaki 95 [self autorelease];
127     return nil;
128     }
129    
130 masakih 370 self.playlist = newPlaylist;
131 masaki 95
132     return self;
133     }
134 masaki 182 - (void)dealloc
135     {
136 masakih 370 self.playlist = nil;
137 masaki 182 [playListWindowController release];
138     [movieWindowController release];
139    
140 masakih 385 [_player release];
141    
142 masaki 182 [super dealloc];
143     }
144 masaki 2
145     - (void)makeWindowControllers
146     {
147 masaki 72 playListWindowController = [[XspfQTPlayListWindowController alloc] init];
148 masaki 2 [self addWindowController:playListWindowController];
149    
150 masaki 72 movieWindowController = [[XspfQTMovieWindowController alloc] init];
151 masaki 42 [movieWindowController setShouldCloseDocument:YES];
152 masaki 2 [self addWindowController:movieWindowController];
153 masaki 298
154 masakih 360 [movieWindowController showWindow:nil];
155 masaki 2 }
156    
157     - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
158     {
159 masakih 370 return [self.XMLDocument XMLDataWithOptions:NSXMLNodePrettyPrint];
160 masaki 2 }
161    
162 masaki 141 - (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
163     {
164 masaki 274 if(!isReadableMovieType(typeName)) {
165 masaki 141 NSData *data = [self dataFromURL:absoluteURL error:outError];
166     if(!data) return NO;
167    
168     return [self readFromData:data ofType:typeName error:outError];
169     }
170    
171 masaki 306 id new = [HMXSPFComponent xspfTrackWithLocation:absoluteURL];
172 masaki 279 if(!new) {
173 masaki 141 if(outError) {
174 masaki 279 *outError = [NSError errorWithDomain:@"XspfQTErrorDomain" code:1 userInfo:nil];
175 masaki 141 }
176     return NO;
177     }
178    
179 masaki 306 id pl = [HMXSPFComponent xspfPlaylist];
180 masaki 141 if(!pl) {
181     return NO;
182     }
183    
184     [[[pl children] objectAtIndex:0] addChild:new];
185    
186 masakih 370 self.playlist = pl;
187     HMXSPFComponent *t = self.trackList;
188     if(!t.title) {
189     t.title = [[[self fileURL] path] lastPathComponent];
190 masaki 141 }
191    
192 masaki 207 [self setFileType:XspfDocumentType];
193 masaki 141 [self setFileURL:nil];
194    
195     return YES;
196     }
197 masaki 2 - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
198     {
199 masaki 274 if(!isXspfFileType(typeName)) {
200 masaki 141 return NO;
201     }
202    
203 masaki 2 NSError *error = nil;
204 masaki 10 NSXMLDocument *d = [[[NSXMLDocument alloc] initWithData:data
205     options:0
206     error:&error] autorelease];
207 masaki 121 if(error) {
208     NSLog(@"%@", error);
209 masaki 272 if(outError) {
210     *outError = error;
211     }
212 masaki 121 return NO;
213     }
214 masaki 2 NSXMLElement *root = [d rootElement];
215 masakih 320 id pl = [HMXSPFComponent xspfComponentWithXMLElement:root];
216 masaki 121 if(!pl) {
217 masaki 306 NSLog(@"Can not create HMXSPFComponent.");
218 masaki 121 return NO;
219     }
220 masakih 370 self.playlist = pl;
221 masaki 2
222 masakih 370 HMXSPFComponent *t = self.trackList;
223     if(!t.title) {
224     t.title = [[[[self fileURL] path] lastPathComponent] stringByDeletingPathExtension];
225 masaki 39 }
226 masaki 272
227 masaki 2 return YES;
228     }
229    
230 masaki 42 - (void)close
231     {
232 masaki 61 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
233 masaki 72 [nc postNotificationName:XspfQTDocumentWillCloseNotification object:self];
234 masaki 61
235 masaki 42 [self removeWindowController:playListWindowController];
236     [playListWindowController release];
237     playListWindowController = nil;
238    
239     [self removeWindowController:movieWindowController];
240     [movieWindowController release];
241     movieWindowController = nil;
242 masakih 329
243 masaki 42 [super close];
244     }
245    
246 masaki 269 #pragma mark### Actions ###
247 masaki 2 - (IBAction)showPlayList:(id)sender
248     {
249     [playListWindowController showWindow:self];
250     }
251 masakih 322 - (IBAction)showHidePlayList:(id)sender
252     {
253     [playListWindowController showHideWindow:self];
254     }
255 masaki 281 - (IBAction)setThumbnailFrame:(id)sender
256 masaki 269 {
257 masakih 370 HMXSPFComponent *currentTrack = self.trackList.currentTrack;
258     QTTime currentQTTime = [self.playingMovie currentTime];
259 masaki 269
260     NSTimeInterval currentTI;
261     QTGetTimeInterval(currentQTTime, &currentTI);
262    
263 masakih 370 HMXSPFComponent *prevThumbnailTrack = self.playlist.thumbnailTrack;
264     NSTimeInterval ti = self.playlist.thumbnailTimeInterval;
265 masaki 269
266 masakih 370 [self.playlist setThumbnailComponent:currentTrack timeIntarval:currentTI];
267 masaki 269
268     id undo = [self undoManager];
269 masaki 281 if(prevThumbnailTrack) {
270 masakih 370 [[undo prepareWithInvocationTarget:self.playlist] setThumbnailComponent:prevThumbnailTrack timeIntarval:ti];
271 masaki 281 [undo setActionName:NSLocalizedString(@"Change Thumbnail frame.", @"Undo Action Name Change Thumbnail frame")];
272 masaki 269 } else {
273 masakih 370 [[undo prepareWithInvocationTarget:self.playlist] removeThumbnailFrame];
274 masaki 281 [undo setActionName:NSLocalizedString(@"Add Thumbnail frame.", @"Undo Action Name Add Thumbnail frame")];
275 masaki 269 }
276     }
277 masaki 281 - (IBAction)removeThumbnail:(id)sender
278 masaki 269 {
279 masakih 370 HMXSPFComponent *prevThumbnailTrack = self.playlist.thumbnailTrack;
280     NSTimeInterval ti = self.playlist.thumbnailTimeInterval;
281 masaki 269
282 masakih 370 [self.playlist removeThumbnailFrame];
283 masaki 269
284 masaki 281 if(prevThumbnailTrack) {
285 masaki 269 id undo = [self undoManager];
286 masakih 370 [[undo prepareWithInvocationTarget:self.playlist] setThumbnailComponent:prevThumbnailTrack timeIntarval:ti];
287 masaki 281 [undo setActionName:NSLocalizedString(@"Remove Thumbnail frame.", @"Undo Action Name Remove Thumbnail frame")];
288 masaki 269 }
289     }
290     - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
291     {
292     SEL action = [menuItem action];
293    
294 masaki 281 if(action == @selector(removeThumbnail:)) {
295 masakih 370 HMXSPFComponent *component = self.playlist.thumbnailTrack;
296 masaki 269 if(!component) return NO;
297     }
298    
299     return YES;
300     }
301 masaki 2
302 masaki 306 - (void)setPlaylist:(HMXSPFComponent *)newList
303 masaki 2 {
304 masakih 385 self.player.playlist = newList;
305 masaki 2 }
306 masaki 306 - (HMXSPFComponent *)playlist
307 masaki 116 {
308 masakih 385 return self.player.playlist;
309 masaki 116 }
310 masaki 306 - (HMXSPFComponent *)trackList
311 masaki 2 {
312 masakih 385 return self.player.trackList;
313 masaki 2 }
314 masaki 171 - (QTMovie *)playingMovie
315     {
316 masakih 385 return self.player.playingMovie;
317 masaki 171 }
318 masaki 242
319 masakih 385 + (NSSet *)keyPathsForValuesAffectingPlayingMovie
320 masaki 171 {
321 masakih 385 return [NSSet setWithObject:@"player.playingMovie"];
322 masaki 171 }
323 masaki 31
324 masaki 71 - (NSXMLDocument *)XMLDocument
325 masaki 31 {
326 masakih 370 id root = self.playlist.XMLElement;
327 masaki 31
328     id d = [[[NSXMLDocument alloc] initWithRootElement:root] autorelease];
329     [d setVersion:@"1.0"];
330     [d setCharacterEncoding:@"UTF-8"];
331    
332     return d;
333     }
334 masaki 42
335 masaki 89 - (void)insertComponentFromURL:(NSURL *)url atIndex:(NSUInteger)index
336     {
337 masaki 306 id new = [HMXSPFComponent xspfTrackWithLocation:url];
338 masaki 89 if(!new) {
339     @throw self;
340     }
341    
342     [self insertComponent:new atIndex:index];
343     }
344 masaki 306 - (void)insertComponent:(HMXSPFComponent *)item atIndex:(NSUInteger)index
345 masaki 55 {
346 masaki 83 id undo = [self undoManager];
347 masaki 86 [undo registerUndoWithTarget:self selector:@selector(removeComponent:) object:item];
348 masakih 370 [self.trackList insertChild:item atIndex:index];
349 masaki 261 [undo setActionName:NSLocalizedString(@"Insert Movie", @"Undo Action Name Insert Movie")];
350 masaki 55 }
351 masaki 306 - (void)removeComponent:(HMXSPFComponent *)item
352 masaki 55 {
353 masakih 370 NSUInteger index = [self.trackList indexOfChild:item];
354 masaki 121 if(index == NSNotFound) {
355 masaki 269 NSLog(@"Can not found item (%@)", item);
356 masaki 121 return;
357     }
358 masaki 83
359     id undo = [self undoManager];
360 masaki 86 [[undo prepareWithInvocationTarget:self] insertComponent:item atIndex:index];
361 masakih 370 [self.trackList removeChild:item];
362 masaki 261 [undo setActionName:NSLocalizedString(@"Remove Movie", @"Undo Action Name Remove Movie")];
363 masaki 55 }
364 masaki 247 - (void)moveComponentFromIndex:(NSUInteger)from toIndex:(NSUInteger)to
365     {
366     id undo = [self undoManager];
367     [[undo prepareWithInvocationTarget:self] moveComponentFromIndex:to toIndex:from];
368 masakih 370 [self.trackList moveChildFromIndex:from toIndex:to];
369 masaki 261 [undo setActionName:NSLocalizedString(@"Move Movie", @"Undo Action Name Move Movie")];
370 masaki 247 }
371 masaki 306 - (void)moveComponent:(HMXSPFComponent *)item toIndex:(NSUInteger)index
372 masaki 247 {
373 masakih 370 NSUInteger from = [self.trackList indexOfChild:item];
374 masaki 247 if(from == NSNotFound) return;
375     [self moveComponentFromIndex:from toIndex:index];
376     }
377 masaki 55
378 masaki 141 - (NSData *)dataFromURL:(NSURL *)url error:(NSError **)outError
379     {
380     NSURLRequest *req = [NSURLRequest requestWithURL:url];
381     NSURLResponse *res = nil;
382     NSError *err = nil;
383     NSData *data = [NSURLConnection sendSynchronousRequest:req
384     returningResponse:&res
385     error:&err];
386     if(err) {
387     if(outError) {
388     *outError = err;
389     }
390     return nil;
391     }
392    
393     return data;
394     }
395    
396 masaki 171
397 masaki 274 inline static BOOL isXspfFileType(NSString *typeName)
398     {
399     return [typeName isEqualToString:XspfDocumentType] || [typeName isEqualToString:XspfUTI];
400     }
401     inline static BOOL isReadableMovieType(NSString *typeName)
402     {
403     return [typeName isEqualToString:QuickTimeMovieDocumentType]
404     || [typeName isEqualToString:MatroskaVideoDocumentType]
405     || [typeName isEqualToString:DivXMediaFormatDocumentType];
406     }
407    
408 masaki 2 @end
409    

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