source: branches/PlayerFramework/CommonMediaPlayer/Media Players/DVD Framework/CMPDVDImporter.m @ 1136

Revision 1136, 6.3 KB checked in by lechium, 4 years ago (diff)

added latest dvdbackup binary, added DVDImport class, register in the MediaPlayerManager?, pretty much just pasted in most of the code from dvd importing from nitoTV with some minor adjustments. not yet tested, but does compile

Line 
1//
2//  CMPDVDImporter.m
3//  CommonMediaPlayer
4//
5//  Created by blunt on 2/15/10.
6//  Copyright 2010 nito, LLC. All rights reserved.
7//
8
9#import "CMPDVDImporter.h"
10
11@implementation CMPDVDImporter
12
13
14- (void) importDVD:(NSArray *)inputArray
15{
16        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
17        Class cls = NSClassFromString( @"GrowlApplicationBridge" );
18        if (cls != nil){
19                [cls setGrowlDelegate:self];
20        }
21       
22        NSString *theDVD = [inputArray objectAtIndex:0];
23        NSString *dvdPath = [inputArray objectAtIndex:1];
24        NSString *defaultOutput = [NSHomeDirectory() stringByAppendingPathComponent:@"Movies/DVD"];
25        int ripErrorMode = 2;
26       
27        NSFileManager *man = [NSFileManager defaultManager];
28        NSDictionary *attrs = [man fileAttributesAtPath:dvdPath traverseLink:YES];
29        NSNumber *dvdSize = [attrs objectForKey:NSFileSize];
30       
31       
32        if ([man fileExistsAtPath:defaultOutput]){
33                if ([man isWritableFileAtPath:defaultOutput]){
34                        NSDictionary *outputAttrs = [man fileAttributesAtPath:defaultOutput traverseLink:YES];
35                        NSNumber *freeSpace = [outputAttrs objectForKey:NSFileSystemFreeSize];
36                        if ([freeSpace isLessThan:dvdSize])
37                        {
38                                NSLog(@"CMPError: not enough space free at path: %@", defaultOutput);
39                                [pool release];
40                                [NSThread exit];
41                                return;
42                        }
43                       
44                } else { // not writable
45                       
46                        NSLog(@"CMPError: not writable at path: %@", defaultOutput);
47                        [pool release];
48                        [NSThread exit];
49                        return;
50                }
51        }
52       
53        NSString *dvdbPath = [[NSBundle bundleForClass:[CMPDVDImporter class]] pathForResource:@"dvdbackup" ofType:@"" inDirectory:@"bin"];
54        NSTask *backupTask = [[NSTask alloc] init];
55        NSMutableArray *bArgs = [[NSMutableArray alloc] init];
56        [bArgs addObject:@"-i"]; //--input=DEVICE
57        [bArgs addObject:theDVD]; //rdisk input
58        [bArgs addObject:@"-M"]; //  -M, --mirror       backup the whole DVD
59        [bArgs addObject:@"-o"];
60        [bArgs addObject:defaultOutput]; //defaults to ~/Movies/DVD
61        [bArgs addObject:@"-n"]; //-n, --name=NAME   
62        [bArgs addObject:[dvdPath lastPathComponent]]; //actual name of the DVD
63        [bArgs addObject:@"-r"];
64       
65        switch (ripErrorMode) {
66                       
67                case 0:
68                        [bArgs addObject:@"a"]; //a=abort: default
69                        break;
70                       
71                case 1:
72                        [bArgs addObject:@"b"]; //b=skip block
73                        break;
74                       
75                case 2:
76                        [bArgs addObject:@"m"]; //m=skip multiple blocks
77                        break;
78                       
79                default:
80                        [bArgs addObject:@"m"]; //m=skip multiple blocks default
81                        break;
82        }
83       
84        [backupTask setLaunchPath:dvdbPath];
85        [backupTask setArguments:bArgs];
86        //NSLog(@"dvdbackup: %@", [bArgs componentsJoinedByString:@" "]);
87        [bArgs release];
88       
89        [backupTask launch];
90        [backupTask waitUntilExit];
91       
92        int termStatus = [backupTask terminationStatus];
93        NSLog(@"dvdbackup terminated with status: %i", termStatus);
94       
95        if (termStatus != 0)
96        {
97                NSString *finalPath = [defaultOutput stringByAppendingPathComponent:[dvdPath lastPathComponent]];
98                NSLog(@"should remove: %@", finalPath);
99                //[man removeFileAtPath:finalPath handler:nil];
100               
101        }
102       
103        [backupTask release];
104        backupTask = nil;
105        [self performSelectorOnMainThread: @selector(_postFinishedImportingNotification)
106                                                   withObject: nil
107                                                waitUntilDone: NO];
108        [pool release];
109       
110}
111
112- (BOOL)canPlay:(NSString *)path withError:(NSError **)error
113{
114        if([super canPlay:path withError:error])
115                return ![CMPDVDPlayer isImage:path]; //return the opposite of isImage, kind of confusing
116        return NO;
117}
118
119- (AGProcess *) dvdImporting
120{
121       
122        NSArray *theProcesses = [AGProcess processesForCommand:@"dvdbackup"];
123        if ([theProcesses count] > 0)
124                return [theProcesses objectAtIndex:0];
125
126        return nil;
127}
128
129- (BOOL)initiatePlaybackWithResume:(BOOL *)resume
130{
131       
132        NSURL *url = [NSURL URLWithString:[asset mediaURL]];
133        NSString *path = [url path];
134        NSString *volumePath = [@"/mnt/Scratch/Volumes" stringByAppendingPathComponent:[path lastPathComponent]];
135        volumePath = [CMPDVDImporter rdiskForPath:volumePath];
136        NSArray *dvdArray = [NSArray arrayWithObjects:volumePath, path, nil];
137        //NSLog(@"volumePath: %@", volumePath);
138        AGProcess *currentTask = [self dvdImporting];
139        if (currentTask != nil)
140        {
141                [currentTask terminate];
142                //if a dvd is already importing, we kill it
143                return NO;
144        }
145        [NSThread detachNewThreadSelector: @selector(importDVD:)
146                                                         toTarget: self
147                                                   withObject: dvdArray];
148       
149        return YES;
150}
151
152+ (NSString *)rdiskForPath:(NSString *)path
153{
154    NSString *rdisk = path;
155    NSString *theName = [path lastPathComponent];
156   
157        NSTask *mnt = [[NSTask alloc] init];
158        NSPipe *pip = [[NSPipe alloc] init];
159        NSFileHandle *handle = [pip fileHandleForReading];
160        NSData *outData;
161        [mnt setLaunchPath:@"/sbin/mount"];
162        [mnt setStandardError:pip];
163        [mnt setStandardOutput:pip];
164        [mnt launch];
165       
166        NSMutableArray *lineArray = [[NSMutableArray alloc] init];
167        while((outData = [handle readDataToEndOfFile]) && [outData length])
168        {
169                NSString *temp = [[NSString alloc] initWithData:outData encoding:NSASCIIStringEncoding];
170                [lineArray addObjectsFromArray:[temp componentsSeparatedByString:@"\n"]];
171                [temp release];
172        }
173       
174       
175        int i;
176        for(i = 0 ; i < [lineArray count] ; i++)
177        {
178                NSArray *arr = [[lineArray objectAtIndex:i] componentsSeparatedByString:[NSString stringWithFormat:@" on /mnt/Scratch/Volumes/%@",theName]];
179                NSArray *arr1 = [[lineArray objectAtIndex:i] componentsSeparatedByString:[NSString stringWithFormat:@" on /Volumes/%@",theName]];
180                if([arr count] > 1)
181                {
182                        rdisk = [arr objectAtIndex:0];
183                        NSArray *arc = [rdisk pathComponents];
184                        rdisk = [NSString stringWithFormat:@"/dev/r%@", [arc lastObject]];
185                        [mnt release];
186                        mnt = nil;
187                        [pip release];
188                        pip = nil;
189                        return rdisk;
190                       
191                } else if([arr1 count] > 1)
192                {
193                        rdisk = [arr1 objectAtIndex:0];
194                        NSArray *arc = [rdisk pathComponents];
195                        rdisk = [NSString stringWithFormat:@"/dev/r%@", [arc lastObject]];
196                        [mnt release];
197                        mnt = nil;
198                        [pip release];
199                        pip = nil;
200                        return rdisk;
201                       
202                }
203        }
204    [mnt release];
205        mnt = nil;
206        [pip release];
207        pip = nil;
208    return rdisk;
209}
210
211NSString * const kCMPDVDFinishedImport = @"kCMPDVDFinishedImport";
212- (void) _postFinishedImportingNotification
213{
214        //NSLog(@"%@ %s", self, _cmd);
215    [[NSNotificationCenter defaultCenter] postNotificationName: kCMPDVDFinishedImport
216                                                        object: self];
217       
218        Class cls = NSClassFromString( @"GrowlApplicationBridge" );
219        if (cls != nil){
220                [cls notifyWithTitle:@"DVD Import Completed" description:@"Your disc is finished importing." notificationName:@"CMPDVDFinishedImport" iconData:nil priority:1 isSticky:NO clickContext:nil];
221        }
222       
223       
224}
225@end
Note: See TracBrowser for help on using the repository browser.