OSDN Git Service

0.2.1
[eliscolors/main.git] / ElisMedia.m
1 //  Copyright (c) 2009 Yanagi Asakura
2 //
3 //  This software is provided 'as-is', without any express or implied
4 //  warranty. In no event will the authors be held liable for any damages
5 //  arising from the use of this software.
6 //
7 //  Permission is granted to anyone to use this software for any purpose,
8 //  including commercial applications, and to alter it and redistribute it
9 //  freely, subject to the following restrictions:
10 //
11 //  1. The origin of this software must not be misrepresented; you must not
12 //  claim that you wrote the original software. If you use this software
13 //  in a product, an acknowledgment in the product documentation would be
14 //  appreciated but is not required.
15 //
16 //  2. Altered source versions must be plainly marked as such, and must not be
17 //  misrepresented as being the original software.
18 //
19 //  3. This notice may not be removed or altered from any source
20 //  distribution.
21
22 //
23 //  ElisMedia.m
24 //  Elis Colors
25 //
26 //  Created by 柳 on 09/09/12.
27 //  Copyright 2009 __MyCompanyName__. All rights reserved.
28 //
29
30 #import "ElisMedia.h"
31
32
33 @implementation ElisMedia
34
35 // QuickTime X を試すためにかなり書き換えた。けど戻した。
36 - (id)initWithMovieFile:(NSString*)path
37 {
38     image = nil;
39     sound = nil;
40     
41     movie = [[QTMovie alloc] initWithFile:path error:nil];   
42     [movie gotoBeginning];
43
44     QTOpenGLTextureContextCreate(kCFAllocatorDefault,
45                                  [[mainView openGLContext] CGLContextObj],
46                                  [[mainView pixelFormat] CGLPixelFormatObj],
47                                  NULL,                  
48                                  &textureContext);
49         
50     SetMovieVisualContext([movie quickTimeMovie], textureContext);
51     
52     attr = [NSDictionary dictionaryWithObjectsAndKeys:
53             QTMovieFrameImageTypeCIImage, QTMovieFrameImageType,
54 #ifdef __SNOW_LEOPARD__
55             [NSNumber numberWithBool:YES], QTMovieFrameImageSessionMode,  // 内部でキャッシュしろ
56 #endif
57             [NSNumber numberWithBool:YES], QTMovieFrameImageHighQuality,  // 画質低下を許さない
58             [movie attributeForKey:QTMovieNaturalSizeAttribute], QTMovieFrameImageSize, // 勝手にリサイズするな
59             [NSNumber numberWithBool:NO], QTMovieFrameImageSingleField, // インターレース解除?
60             nil];
61     
62     speed = 1.0;
63     _path = path;
64     playing = NO;
65     
66     [movie setVolume:0.0f];
67     
68     if([[NSWorkspace sharedWorkspace] type:[[NSWorkspace sharedWorkspace] typeOfFile:path error:nil] 
69               conformsToType:@"com.apple.quartz-composer-composition"])
70         isQuartz = YES;
71     else
72         isQuartz = NO;
73     
74     return self;
75 }
76
77 - (id)initWithImageFile:(NSString*)path
78 {
79     movie = nil;
80     textureContext = nil;
81     sound = nil;
82     text = nil;
83
84     image = [[CIImage alloc] initWithContentsOfURL:[NSURL fileURLWithPath: path]];
85
86     speed = 1.0;
87     _path = path;
88     return self;
89 }
90
91 - (id)initWithSoundFile:(NSString*)path
92 {
93     movie = nil;
94     image = nil;
95     textureContext = nil;
96     sound = [[QTMovie alloc] initWithFile:path error:nil];
97     [sound setVolume:0.2]; // あまりにうるさい。
98     speed = 1.0;
99     _path = path;
100     return self;
101 }
102
103 - (id)initWithText:(NSAttributedString*)t
104 {
105     NSImage* im;
106     movie = nil;
107     sound = nil;
108     text = [t copy];
109 //    [attr retain];
110 //    [attr setValue:[NSFont fontWithName:@"HiraKakuPro-W3" size:24.0f] forKey:NSFontAttributeName];
111 //    [attr setValue:[NSColor colorWithCalibratedRed:255 green:255 blue:255 alpha:255] forKey:NSForegroundColorAttributeName];
112     NSRect size = [t boundingRectWithSize:NSMakeSize(4000, 3000) options:NSStringDrawingUsesLineFragmentOrigin];
113     im = [[NSImage alloc] initWithSize:size.size];
114     [im lockFocus];
115 //    t = [[NSAttributedString alloc] initWithString:@"string"];
116     [[NSGraphicsContext currentContext] setShouldAntialias:YES];
117     [t drawInRect:size];
118     [im unlockFocus];
119     image = [[CIImage alloc] initWithData:[im TIFFRepresentation]];
120 //    [im release];
121     speed = 1.0;
122     return self;
123 }
124
125 - (id)initWithQuartzFile:(NSString*)path
126 {
127     return [self initWithMovieFile:path];
128 }    
129
130 // レガシーなので捨てました。
131 // もう一度試してる。
132 - (CIImage*)getFrameForTime:(CVTimeStamp*)timeStamp
133 {
134     CVImageBufferRef currentFrame;
135     CIImage* ret;
136     
137     if(movie){
138         QTVisualContextCopyImageForTime(textureContext, NULL, timeStamp, &currentFrame);
139         ret = [CIImage imageWithCVImageBuffer:currentFrame];
140         CVOpenGLTextureRelease(currentFrame);
141         return ret;
142     }else if(image){
143         return image;
144     }
145     return nil;
146 }
147
148 - (CIImage*)getFrameForQTTime:(QTTime)time
149 {
150     // 64ビットでframeImageAtTimeメソッドは使えないみたい。どうしろと。
151     time.timeValue *= speed;
152     if(movie)
153         return [movie frameImageAtTime:time withAttributes:attr error:nil];
154     else if(image)
155         return image;
156     return nil;
157 }
158
159 - (void)releaseContext
160 {
161     if(movie)
162         QTVisualContextTask(textureContext);
163 }
164
165 - (void)setCurrentTime:(QTTime)time
166 {
167     time.timeValue *= speed;
168     if(movie){
169         [movie setAttribute:[NSValue valueWithQTTime:time] forKey:QTMovieCurrentTimeAttribute];
170         MoviesTask([movie quickTimeMovie], 0);
171     }
172     if(sound && !playing){
173         [sound setCurrentTime:time];
174         MoviesTask([sound quickTimeMovie], 0);
175     }
176 }
177
178 - (void)play
179 {
180     if(movie && !playing && usingStampMode){
181 //        [movie play];
182         [movie setRate:speed];
183         playing = YES;
184     }
185     if(sound && !playing){
186         [sound play];
187         playing = YES;
188     }
189 }
190
191 - (void)stop
192 {
193     if(movie && YES && usingStampMode){
194         [movie stop];
195         playing = NO;
196     }
197     if(sound && YES){
198         [sound stop];
199         playing = NO;
200     }
201 }
202
203 - (QTTime)duration
204 {
205     if(movie){
206         if(isQuartz) return QTMakeTime(30, 1);
207         QTTime d = [movie duration];
208         d.timeValue /= speed;
209         float s = (float)d.timeValue/d.timeScale;
210         if(s > 60*10) return QTMakeTime(60*10, 1);
211         return d;
212     }
213     if(sound)
214         return [sound duration];
215     if(image)
216         return QTMakeTime(10, 1);
217 }
218
219 - (void)finalize
220 {
221     if(movie){
222         NSLog(@"movie finalize");
223         [movie stop];
224         SetMovieVisualContext([movie quickTimeMovie], NULL);
225         movie = nil;
226         CFRelease(textureContext);
227     }
228     
229     [super finalize];
230 }
231
232 - (QTTrack*)getSoundTrack
233 {
234     int size;
235     NSArray* tracks;
236     
237     if(sound){
238         tracks = [sound tracksOfMediaType:QTMediaTypeSound];
239         size = [tracks count];
240         if(size > 0) return [tracks objectAtIndex:0];
241     }
242     else if(image)
243         return nil;
244     
245     return nil;
246 }
247
248 - (NSString*)type
249 {
250     if(text)
251         return @"text";
252     if(image)
253         return @"image";
254     if(movie)
255         return @"movie";
256     if(sound)
257         return @"sound";
258     
259     return @"other";
260 }
261
262 - (NSString*)path
263 {
264     return _path;
265 }
266
267 - (void)encodeWithCoder:(NSCoder*)encoder
268 {
269     int flag;
270     [encoder encodeObject:_path forKey:@"path"];
271     [encoder encodeObject:text forKey:@"text"];
272     [encoder encodeFloat:speed forKey:@"speed"];
273     
274     if(movie) flag = 0;
275     else if(sound) flag = 1;
276     else if(text) flag = 3;
277     else if(image) flag = 2;
278     
279     [encoder encodeInt:flag forKey:@"flag"];
280 }
281
282 - (id)initWithCoder:(NSCoder*)coder
283 {
284     int flag;
285     NSString* path = [coder decodeObjectForKey:@"path"];
286     NSAttributedString* t = [coder decodeObjectForKey:@"text"];
287     flag =  [coder decodeIntForKey:@"flag"];
288     
289     id ret;
290     
291     if(flag == 0)
292         ret = [self initWithMovieFile:path];
293     else if(flag == 1)
294         ret = [self initWithSoundFile:path];
295     else if(flag == 2)
296         ret = [self initWithImageFile:path];
297     else
298         ret = [self initWithText:t];
299     
300     speed = [coder decodeFloatForKey:@"speed"];
301     
302     return ret;
303 }
304
305 - (QTMovie*)getSoundMovie
306 {
307     if(sound)
308         return sound;
309     else
310         return nil;
311 }
312
313 - (NSAttributedString*)text
314 {
315     return text;
316 }
317
318 - (void)setText:(NSAttributedString*)t
319 {
320     [self initWithText:t];
321 }
322
323 - (NSRect)size
324 {
325     if(sound)
326         return NSZeroRect;
327     if(movie){
328         NSSize s;
329         s = [[movie attributeForKey:QTMovieCurrentSizeAttribute] sizeValue];
330         return NSMakeRect(0, 0, s.width, s.height);
331     }
332     if(image){
333         CGRect c = [image extent];
334         return *(NSRect*)&c;
335     }
336 }
337
338 - (float)speed
339 {
340     return speed;
341 }
342
343 - (void)setSpeed:(float)s
344 {
345     speed = s;
346 }
347
348 - (void)setVolume:(float)v
349 {
350     [sound setVolume:v];
351 }
352
353 - (BOOL)isQuartz
354 {
355     return isQuartz;
356 }
357
358 @end