Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/divideMovieViewController/XspfQTDocument.m

Parent Directory Parent Directory | Revision Log Revision Log


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

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