본문 바로가기
프로그래밍/iOS

YouTube에 동영상 업로드

by 백룡화검 2012. 8. 2.

출처 : http://blog.naver.com/saturna?Redirect=Log&logNo=60125222351


아이폰, 아이패드 앱에서 YouTube에 동영상을 업로드 할때

Google에서 제공하는 gdata-objectivec-client api를 사용한다.


http://code.google.com/p/gdata-objectivec-client/

위 URL에서 gdata api를 다운로드한다.


다운로드한 소스를 개발중인 앱의 프로젝트에 추가하는 방법

1. 다운로드한  gdata api의 GData.xcodeproj 를 실행하여 xcode에서 gdata project를 open 한다.

2. 개발중의 앱의 프로젝트도 xcode로 open 한다.

    2개의 프로젝트가 오픈된 상태이다.

3. GData 프로젝트의 "GData Source" group을 개발중인 앱의 프로젝트에 drag & drop하여 추가한다.

    추가할 위치는 기호에 맞게 적절한 곳에... (난 "Other Sources" group에 추가했다)

    추가할 때 모두 복사하지 말고, reference만 하도록 한다.

4. 이 상태에서 빌드를 하면 몇가지 에러가 발생한다.

    1) Security.framework, libxml2.dylib framework 추가하고 

    2) 다음과 같이 build configuration을 추가한다.

         Other Linker Flags : -lxml2

         Header Search Path 에 $SDKROOT/usr/include/libxml2를 추가한다.


이 방법은 아래글 참조

ios에서 gdata-objectivec-client api 사용하기



다운로드한 gdata api의  Example/OAuthSampleTouch 폴더에 

아이폰, 아이패드 등의 touch device에서의 oauth 예제가 있다.

(OAuthSampleRootViewControllerTouch 클래스의 signInToGoogle 메소드)


이 예제는 Google 인증만 받을 수 있으며, YouTube에 동영상을 업로드하려면

Example/YouTubeSample 폴더의 예제를 참고한다.

(YouTubeSampleWindowController 클래스의 uploadVideoFile 메소드)


YouTubeSampleWindowController 클래스는 Mac OS에서 YouTube로

동영상을 업로드하는 예제이고, 

YouTube username/password를 통해 인증하는 방식이라

OAuth를 통해 인증하여 동영상을 업로드 하는 예제로는 마땅치 않다.


OAuthSampleTouch와 YouTubeSample 예제,  그리고 적당한 시간의 googling

이 3박자가 잘 맞아야만 한다........ 

.........좀 고로운 작업이다. 일주일간 고군분투하여 불현듯 동영상 업로드가 되었다.



Google OAuth 인증 후 YouTube에 동영상 업로드


0Google 및 YouTube계정을 만들고, Google OAuth사용을 위해 Developer Key를 발급받는다다.


1. Google + YouTube OAuth 로그인 WebView 오픈을 위한 소스.

   shouldFetchGoogleUserInfo property를 NO로 설정해야만 Google과 YouTube OAuth 화면이 나온다.

   물론 shouldFetchGoogleUserInfo = NO로 설정하지 안아도 구글계정으로 로그인하여 동영상을 업로드할 수 있다.

   하지만 구글계정이 아닌 유튜브 계정으로 로그인 할 수 없다.

   (단 이 설정을 NO로 설정하면 GDataOAuthAuthentication에서 구글계정을 확인 할 수 없다....) 

 NSString* currentLanguage = ...;

  NSString* googleAPIServiceName = ...;

NSString* scope = [[GDataServiceGoogleYouTube class] authorizationScope];

GDataOAuthViewControllerTouch* oAuthViewController =[[[GDataOAuthViewControllerTouch alloc]

  initWithScope:scope

  language:currentLanguage

  appServiceName:googleAPIServiceName

  delegate:self

  finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease];

[GDataOAuthViewControllerTouch authForGoogleFromKeychainForName:googleAPIServiceName];

oAuthViewController.signIn.shouldFetchGoogleUserInfo = NO;

[[self navigationController] pushViewController:oAuthViewController animated:NO]; 


2. WebView에서 OAuth 인증후 결과값을 받는 GDataOAuthViewControllerTouch 클래스의 delegate 메소드이다.

   인증 결과값을 auth 변수에서 확인할 수 있다.

   이 값을 적적할 변수에 보관한다. (난 appDelegate의 변수에 보관했다)

 //GDataOAuthViewControllerTouch delegate

- (void)viewController:(GDataOAuthViewControllerTouch*)viewController

      finishedWithAuth:(GDataOAuthAuthentication*)auth

                 error:(NSError *)error

{

     // auth  keeping..

     // m_youTubeAuthentication = [auth retain]

}

3. 인증여부 확인 및 로그아웃..

여기까지 하면 인증 및 로그인 과정이 완료된다.

인증여부를 확인하는 방법은 

적절한 곳에 변수할당한 GDataOAuthAuthentication 인스턴스의 canAuthorize 메소드의 BOOL 값을 통해 알 수 있다.

[auth canAuthorize]


로그아웃은 인증후 적절한 곳에 보관한 GDataOAuthAuthentication 인스턴스를 release, nil로 처리했다.


참고로

GDataOAuthViewControllerTouch 클래스의 initialHTMLString, webView 등의 property 를

적절하게 설정해서 OAuth view를 디자인 할 수 있다. 


<OAuth WebView loading 화면>                                        <OAuth WebView 화면>

   


4. 동영상 업로드

    video category는 kGDataSchemeYouTubeCategory 상수에 정의된 scheme 파일에서 확인할 수 있다.

    (Film, Entertainment, Travel ...)

    GDataMedia*** 클래스 관련 설정은 Example/YouTubeSample 참고.


- (void)uploadVideo

{

        // 인증완료후 보관해둔 GDataOAuthAuthentication 인스턴스 사용.

        GDataOAuthAuthentication * youTubeAuthentication = ...


        // Google developer key

        NSString* googleDevKey = ...


GDataServiceGoogleYouTube* youTubeService = [[GDataServiceGoogleYouTube alloc] init];

[youTubeService setShouldCacheDatedData:YES];

[youTubeService setServiceShouldFollowNextLinks:YES];

[youTubeService setIsServiceRetryEnabled:YES];


[youTubeService setAuthorizer:youTubeAuthentication];

[youTubeService setYouTubeDeveloperKey:googleDevKey];


// gather all the metadata needed for the mediaGroup

        NSString* videoTitle = ...

NSString* videoCategory = ...

NSString* videoKeywords = ...
NSString* videoDesc = ...

        BOOL isPrivate = NO; //공개여부

NSString* videoFilePath = ...


GDataMediaTitle* aMediaTitle = [GDataMediaTitle textConstructWithString:videoTitle];

GDataMediaCategory* aMediaCategory = [GDataMediaCategory mediaCategoryWithString:videoCategory];

[aMediaCategory setScheme:kGDataSchemeYouTubeCategory];

GDataMediaKeywords* aMediaKeywords = [GDataMediaKeywords keywordsWithString:videoKeywords];

GDataMediaDescription* aMediaDesc = [GDataMediaDescription textConstructWithString:videoDesc];


GDataYouTubeMediaGroup* aMediaGroup = [GDataYouTubeMediaGroup mediaGroup];

[aMediaGroup setMediaTitle:aMediaTitle];

[aMediaGroup setMediaDescription:aMediaDesc];

[aMediaGroup addMediaCategory:aMediaCategory];

[aMediaGroup setMediaKeywords:aMediaKeywords];

[aMediaGroup setIsPrivate:isPrivate];


NSData* mediaData = [NSData dataWithContentsOfFile:videoFilePath];


// TODO: mimeType

NSString* mimeType = [GDataUtilities MIMETypeForFileAtPath:videoFilePath

   defaultMIMEType:@"video/mp4"];


// create the upload entry with the mediaGroup and the file data

GDataEntryYouTubeUpload* entry;

entry = [GDataEntryYouTubeUpload uploadEntryWithMediaGroup:aMediaGroup

  data:mediaData

  MIMEType:mimeType

  slug:[videoFilePath lastPathComponent]];


SEL progressSel = @selector(youTubeServiceTicket:deliveredByteCount:ofTotalByteCount:);

[youTubeService setServiceUploadProgressSelector:progressSel];


        // 이부분이 가장 중요할 듯 싶다...

        // "default" 사용자로 업로드 URL을 만드는 부분이다.

NSURL* uploadURL;

uploadURL = [GDataServiceGoogleYouTube youTubeUploadURLForUserID:kGDataServiceDefaultUser];


GDataServiceTicket *ticket;

ticket = [youTubeService fetchEntryByInsertingEntry:entry

 forFeedURL:uploadURL

   delegate:self

  didFinishSelector:@selector(youTubeServiceTicket:finishedWithEntry:error:)];

[youTubeService autorelease];

}


// 동영상 파일의 업로드 된 byte size를 체크하기 위한 메소드....

// dataLength의 용도를 모르겠다... 값이 0으로 전달된다.... 어딘가에서 설정해야 하나???

- (void)youTubeServiceTicket:(GDataServiceTicket*)ticket

  deliveredByteCount:(unsigned long long)numberOfBytesRead

ofTotalByteCount:(unsigned long long)dataLength

{

// 

}


// 동영상 업로드 성공/실패 여부 판별....

// entry 파라미터로 업로드 된 동영상 URL을 알 수 있다.

// entry는 GDataEntryBase의 하위클래스인 GDataEntryYouTubeUpload 클래스이다.


- (void)youTubeServiceTicket:(GDataServiceTicket*)ticket

   finishedWithEntry:(GDataEntryBase*)entry

   error:(NSError*)error

{

if (error == nil)

{

// succeeded

                GDataEntryYouTubeUpload* uploadedEntry = (GDataEntryYouTubeUpload*)entry;

                GDataYouTubeMediaGroup* mediaGroup = [uploadedEntry mediaGroup];

                GDataMediaContent* mediaContent = [[mediaGroup mediaContents] objectAtIndex:0];


                NSURL* aURL = [[NSURL alloc] initWithString:[mediaContent URLString]];

               if (DEBUG) NSLog(@"===> aURL : %@", aURL);

              

              //  YouTube의 동영상 URL을 오픈하면 YouTuve app이 실행된다.

              [[UIApplication sharedApplication] openURL:aURL];

}

else

{

// failed

}

}



여기까지가   OAuth  인증 및 동영상 업로드를 위한

계략적인 과정이다.


GDataOAuthViewControllerTouch 클래스의 signIn property 인

GDataOAuthSignIn 클래스의 shouldFetchGoogleUserInfo property를 NO로 설정하는 부분과

upload URL을 만들때 kGDataServiceDefaultUser 상수로 정의되 default 사용자를 사용하는 부분

이 2가지만 주의하자!!


shouldFetchGoogleUserInfo = NO로 설정하지 않아도 된다.

단 YouTube계정을 사용할 수 없다. 구글 이메일 계정을 사용해야 한다.