QOOK TV + SKYHD CaptureX HDMI

집에 혼자 있을때는 거의 아프리카 방송 틀어놓는데 만날 심슨만 보니까 질리기도 하고 밤에 케이블 티비 홈쇼핑 채널도 좀 보고싶고 그래서 IPTV 라는걸 써보기로 했다. 지금 쓰고 있는 인터넷이 KT꺼니까 QOOK TV로 하기로 하고 홈페이지 들어가서 뭘로 신청할까 살펴보다가 일단 제일 좋은거 한두 달 써보고 다른걸로 바꾸자! 하고 무려 월 3만원짜리 QOOK TV 스카이라이프 프리미엄 신청을 했다. 다음날 상담 전화 와서 프리미엄 채널 요금이 부담된다면 이코노미 가격으로 스탠다드 볼 수 있게 프로모션 중이니 이걸로 하지 않겠냐고 했지만 꿋꿋이 프리미엄 채널을 지켜냈다. 훗.

컴퓨터에 박혀있는 TV카드가 HDTV 수신카드니까 HD 방송을 볼 수 있겠지? 하고 별 생각없이 있었는데 인터넷을 좀 찾아보니 TV 수신카드는 그냥 동축케이블 단자로 들어오는 HD 방송 신호를 디코딩 해줄 뿐이고 외부 입력은 S-VHS 라고 하는 해상도 480i 짜리 입력만 된다고 한다. 잠시나마 TV를 지를 수 있는 좋은 기회라는 생각이 들었지만 정신차리고 인터넷을 더 찾아보니 캡쳐보드라는게 있단다. 이름은 많이 들어봤지만 뭘 캡쳐하길래 기계가 필요하지 하고 지나쳤는데 이건 TV 수신 카드랑 비슷한데 수신은 안되고 외부 입력만 받아주는 하드웨어라고 한다.

캡쳐보드 종류도 그렇게 많지 않고 가격도 비싸고 해서 선택의 여지가 별로 없다. 사서 쓸 수 있는건 SKYHD CaptureX HDMI 요거 하나. HDMI, 컴포넌트, 컴포지트, SVHS 입력을 지원한다고 한다. 영상 전송 규격에 대해서 한참 검색을 해본 결과 HDMI가 화질이 제일 좋고 QOOK TV 셋탑박스에서 HDMI 출력을 지원해준다고 한다. 근데 HDMI 전송은 화질이 너무 좋아서 불법복제가 쉬워질 우려가 있기 때문에 이 캡쳐보드에서는 동영상 캡쳐 지원이 안된다고 함. 이거 되게 하려면 제조사에서 라이선스를 사야 하는데 그러면 하드웨어 가격이 엄청 올라간다네?

그렇게 캡쳐보드도 사다 설치해놓고 평일이라 회사에 오후 휴가도 내놓고 집에와서 청소하고 샤워하고 다소곳이 앉아서 TV 설치 기사를 기다렸는데 바빠서 오늘 설치를 못해주겠다고 한다. 홧김에 낮술먹고 잤더니 애매한 시각에 깨버려서 밤에 잠도 못자고 억울해서 엉엉 울다 동틀 무렵 잠이 들었다.

아무튼 그래서 토요일 아침에 설치 기사가 왔는데 옥상 문이 열려있나요? 하길래 뭔소린가 했더니 SkyLife 안테나를 설치해야 한다고! 인터넷에서 대충 검색해보고 SkyLife 채널도 그냥 인터넷으로 전송되는 줄 알았더니 접시 안테나를 설치해야 하는 상품이었다. 전화해서 물어보면 되는걸 지식인 검색해본 내가 멍충이.. 암튼 죄송죄송하고 일반 상품으로 변경해서 오후에 설치해달라고 했다. 그래서 설치 했다.

공중파를 비롯해 영화 등 HD 채널이 꽤 있는데 화질은 기대했던 만큼 마음에 든다. HDMI 말고 컴포넌트 케이블로 연결 해도 1080i 해상도 지원이 되는데 HDMI 쪽이 약간 어둡고 샤프하고 해상력이 좋아 보이지만 크게 차이는 나지 않아서 동영상 녹화가 가능한 컴포넌트 케이블로 연결해 두었다. HDMI 단자 활용을 못하는게 안타까우니 나중에 게임기나 사다 꼽으면 좋을 듯. 캡쳐보드에 기본 포함된 프로그램에서 녹화하려면 따로 상용 코덱이 있어야 했는데 최근에 업데이트 되면서 Mainconcept 코덱이라는걸 기본으로 포함해줬다. tp 파일로 녹화가 되는데 비트레이트좀 높여주면 용량이 커서 그렇지 화질은 괜찮은 것 같다.

QOOK TV 자체에 대해서는 불만족스러운 점이 많음.

  • 셋탑박스가 너무 크고 못생겼다. 세로로 세워둘 수 없다.
  • 다운돼서 리모컨 입력도 본체의 슬립버튼도 안먹히는 경우가 이틀에 한 번 정도 있다. 이런 경우에는 셋탑박스의 전원을 껐다 켜야 함.
  • 사용자 입력에 대한 반응이 거의 1초쯤 걸린다. 채널 변경할때마다 노래방에서 예약하는 기분. 그래서 아래로 세칸 움직여 선택하고 서브메뉴로 가서 확인 같은 액션을 하려면 커서의 움직임을 예측할 수 있는 능력과 정확한 클릭이 필요하다.
  • 채널 내비게이션이 불편하다. 티비 틀어놓고 채널 하나씩 올려가며 지금 뭐하나 보기에는 채널이 많고 채널 전환 딜레이가 길어 짜증이 나기 때문에(버튼 누르고 약 1.5초) 채널 목록을 쭉 나열해주는 메뉴에 들어가서 보는데 한번에 표시되는 정보 양도 적고 페이지 이동도 불편하고 그래서 웬만하면 채널 바꾸기 싫어지게 하는 효과가 있다.
  • 리모컨이 사용이 불편하다. 아직 한 달도 안써봐서 그런지 모르겠지만 일단 버튼이 너무 많고 가장 많이 쓰는 채널 버튼이 오른손 잡이가 누르기 되게 애매한 위치에 있다(오른쪽 이미지에서 방향키 버튼 오른쪽이 채널 버튼). 채널 두 개만 달랑 있는 리모컨도 같이 제공해줬으면 좋겠음. 웃긴건 이 와중에 채널 올리는 버튼에 찾기 쉬우라고 키보드 F, J 키 처럼 돌기를 만들어 놨음 ㅋ
  • 최첨단 TV 답게 VOD, 온라인 게임, 인터넷 검색, 노래방 등등 기능은 되게 많은데 미치도록 느려서 쓰기 싫다.

드라마 다시 보기 같은건 일주일 지나면 무료로 볼 수 있어서 좋고 화질 기대한 대로 나와주고 안테나 안꼽아도 되는거 말고는 IPTV 최고! 할만한건 없는 것 같다. 예전에 아날로그 티비에 동네 케이블 티비 꼽아서 쓸때는 채널 누르면 0.2초만에 채널 딱 바뀌고 리모컨은 내 손에 딱 맞아서 쳐다볼일도 없고 그랬는데 채널수랑 화질만 좋아졌지 사용자 경험은 점점 안좋게 퇴보하고 있는 것 같다.

아무튼 첫날 며칠간은 아직 IPTV는 쓸게 못되니 좀 더 문명이 발전할때를 기다려야 할 것 같다는 생각이 들었는데 뭐 보다보니 불편함도 당연하게 느껴지고 TV는 보고 싶은데 케이블 길게 뽑아다 연결하기도 귀찮고 그래서 그냥 쓸까 말까 다른 회사껄 써볼까 하고 이런 저런 생각을 하고 있었는데..

충동적으로 가입한 유료채널에서 뿜어져 나오는 HD 영상앞에 무릎을 꿇고 오래오래 행복하게 살았답니다.

저작자 표시 비영리

'평범한 얘기 > 잡담거리' 카테고리의 다른 글

QOOK TV + SKYHD CaptureX HDMI  (4) 2010/04/24
Twitter  (3) 2009/04/25
주산  (12) 2008/07/29
졸업  (10) 2008/07/22
쥬크온 일 안하냐  (6) 2008/05/28
책 읽기  (4) 2008/04/15
태그 : IPTV, 리뷰

iPhone 에서 OAuth 라이브러리 사용하기

지난 주에 아이폰에 OAuth 컨슈머 라이브러리 돌리는데 삽질을 너무 많이 해서 반성하는 의미로 포스팅 해본다. http://oauth.net에 있는 라이브러리는 아이폰에 바로 쓸 수 없어서 약간 손을 봐야하는데 누군가 이미 해놓은 것도 있지만 기본(?) 라이브러리로 한번 해봤다. 붙이는건 그렇게 어렵지 않은데 아이폰에 써드파티 바이너리 프레임웍 추가 안되는거랑 Security.framework 내용이 Mac의 것과 다르다는 걸 몰라서 시간을 엄청 허비했음.

  1. OAuthConsumer 라이브러리를 체크아웃 한다.

    svn checkout http://oauth.googlecode.com/svn/code/obj-c/ .

  2. 프레임웍으로 빌드해서 넣으면 깔끔하겠지만 아이폰에는 그렇게 넣을 수 없으니 소스를 직접 넣는다. 다운받은 OAuthConsumer 디렉토리 아래에서 필요한 파일만 남기고 모두 삭제한다.

    rm -rf English.lproj OAuthConsumer.xcodeproj *.plist *.pch *.rb *Test.?

  3. Xcode에서 OAuthTest 라는 이름의 View-Based Application 하나를 생성한다.

  4. Finder에서 OAuthConsumer 디렉토리를 끌어다 Groups & Files 창의 Classes 아래에 놓는다. 파일을 복사할꺼니까 끌어다 놓을때 뜨는 'Copy items into destination group's folder'에 체크하고 Add 한다.

  5. 이 상태에서 빌드를 해보면 OAToken_KeychainExtensions.m 파일에서 에러가 난다. 원래 Mac Cocoa 환경이라면 Security.framework 라이브러리를 추가해서 컴파일 할 수 있지만 아이폰용 Security.framework 라이브러리는 맥용과 달라서 OAToken_KeychainExtensions.m 파일을 컴파일 시킬 수 없다. 하지만 이 파일은 꼭 필요한건 아니고 나중에 OAuth 인증 끝나고 토큰과 시크릿을 키체인에 안전하게 보관할 수 있게 도와주는 유틸리티인데 필요하면 알아서 구현하고 일단 지워도 문제 없다. 파일 목록에서 OAToken_KeychainExtensions.? 파일을 삭제하고 빌드하면 일단 문제없이 컴파일이 될 것이다.

  6. 시작하기 전에 OAuthConsumer.h 파일을 열어서 import 경로를 올바른 경로로 바꾸어주자.

    #import <Foundation/Foundation.h> #import <OAuthConsumer/OAToken.h> #import <OAuthConsumer/OAConsumer.h> #import <OAuthConsumer/OAMutableURLRequest.h> ...

    이걸 아래처럼 변경.

    #import <Foundation/Foundation.h> #import "OAToken.h" #import "OAConsumer.h" #import "OAMutableURLRequest.h" ...

  7. 이제 OAuthTestViewController.xib 파일을 열어서 아래 그림처럼 웹뷰, 'Get Request Token' 버튼, 'Get Access Token' 버튼, PIN 번호를 입력받을 텍스트 필드가 있는 화면을 생성한다. 'Get Request Token' 버튼을 누르면 Request Token을 얻어와서 트위터의 Authorize URL로 이동시키고, 사용자가 로그인 한 후 보여지는 PIN 번호를 넣고 'Get Access Token' 버튼을 누르면 Access Token을 가져올 것이다.

  8. 위에서 추가한 웹뷰, 텍스트필드의 아웃렛 변수와 두 버튼에 연결될 액션 메서드를 만들고 연결한다.

    #import <UIKit/UIKit.h> @interface OAuthTestViewController : UIViewController { UIWebView *webView; UITextField *textField; } @property (nonatomic, retain) IBOutlet UIWebView *webView; @property (nonatomic, retain) IBOutlet UITextField *textField; - (IBAction)requestTokenButton:(UIButton *)sender; - (IBAction)accessTokenButton:(UIButton *)sender; @end

  9. 먼저 'Get Request Token' 버튼을 눌렀을때 Request Token을 얻어와서 로그에 찍어보자. 아래처럼 호출하도록 requestTokenButton: 메서드를 작성하고 성공/에러시에 호출될 델리게이트 메서드도 만든다.

    #import "OAuthConsumer.h" ... - (IBAction)requestTokenButton:(UIButton *)sender { OAConsumer *consumer = [[OAConsumer alloc] initWithKey:@"Z0DxPl4q7kmSOgh3LTpV4Q" secret:@"LWryiOYBAHJ58PX9Yn1yG5bzDwpMJiksqpXxfst7kcU"]; NSURL *url = [[NSURL alloc] initWithString:@"http://twitter.com/oauth/request_token"]; OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url consumer:consumer token:nil realm:@"http://twitter.com/" signatureProvider:nil]; [request setOAuthParameterName:@"oauth_callback" withValue:@"oob"]; OADataFetcher *fetcher = [[OADataFetcher alloc] init]; [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(requestTokenTicket:didFinishWithData:) didFailSelector:@selector(requestTokenTicket:didFailWithError:)]; [consumer release]; [url release]; [request release]; [fetcher release]; } - (void)requestTokenTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { if (ticket.didSucceed) { NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; OAToken *token = [[OAToken alloc] initWithHTTPResponseBody:responseBody]; NSLog(@"Request Token: key=%@, secret=%@", [token key], [token secret]); [token release]; [responseBody release]; } else { NSLog(@"Finish but did not succeed."); } } - (void)requestTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error { NSLog(@"Error: %@", [error localizedDescription]); }

    위와 같이 작성해서 실행해보면 requestTokenTicket:didFailWithError: 쪽으로 떨어지면서,

    Operation could not be completed. (NSURLErrorDomain error -1012.)

    이런 메시지가 떨어진다. 이유는,

    [request setOAuthParameterName:@"oauth_callback" withValue:@"oob"];

    이 부분 때문인데 oauth_callback 이라는 파라미터를 추가하고 싶어서 이렇게 적었으면 이 파라미터를 포함하여 시그니쳐를 생성해야 하는데 OAuthConsumer 라이브러리에서는 추가된 파라미터를 제외하고 시그니처를 생성해 요청했고 결과적으로 트위터에서 시그니처가 틀리다는 이유로 200 OK가 떨어지지 않는 상태이다(버그이거나 OAuth 1.0a 스펙을 고려하지 않아서인 듯). 추가된 파라미터를 포함하여 시그니처를 생성하도록 OAMutableURLRequest.m 파일을 수정해보자. 파일을 열어서 _signatureBaseString 메서드 중간쯤에,

    ... for (OARequestParameter *param in [self parameters]) { [parameterPairs addObject:[param URLEncodedNameValuePair]]; } for(NSString *parameterName in [[extraOAuthParameters allKeys] sortedArrayUsingSelector:@selector(compare:)]) { [parameterPairs addObject:[[OARequestParameter requestParameterWithName:parameterName value:[extraOAuthParameters objectForKey:parameterName]] URLEncodedNameValuePair]]; } NSArray *sortedPairs = [parameterPairs sortedArrayUsingSelector:@selector(compare:)]; NSString *normalizedRequestParameters = [sortedPairs componentsJoinedByString:@"&"]; ...

    이렇게 for 루프를 하나 추가한다. 이제 다시 실행해서 'Get Request Token' 버튼을 눌러보면,

    2010-03-05 17:09:40.438 OAuthTest[1691:207] Request Token: key=wyGw0VUSE79MTuVm0iqs7ZdWiPI3ZRJWCZ2k6P73w, secret=AUGrkHfx3nr6xb9Q5dUbNQzykZQvFJ62WW90BojT8

    콘솔에 이렇게 찍히면서 정상적으로 토큰을 얻어올 수 있다.

  10. 이제 Request Token을 얻어왔으니 토큰을 임시로 저장하고 트위터의 Authorize URL을 호출한다. 아래처럼 OAuthTestViewController.h 파일을 수정하고,

    #import <UIKit/UIKit.h> @class OAServiceTicket; @class OAToken; @interface OAuthTestViewController : UIViewController { UIWebView *webView; UITextField *textField; OAToken *requestToken; } @property (nonatomic, retain) IBOutlet UIWebView *webView; @property (nonatomic, retain) IBOutlet UITextField *textField; @property (nonatomic, retain) OAToken *requestToken; ...

    아래처럼 OAuthTestViewController.m 파일을 수정한다.

    if (ticket.didSucceed) { NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; OAToken *token = [[OAToken alloc] initWithHTTPResponseBody:responseBody]; NSLog(@"Request Token: key=%@, secret=%@", [token key], [token secret]); self.requestToken = token; [token release]; [responseBody release]; NSString *authorizeURL = [[NSString alloc] initWithFormat:@"http://twitter.com/oauth/authorize?oauth_token=%@", [self.requestToken.key URLEncodedString]]; [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:authorizeURL]]]; [authorizeURL release]; } ...

    이제 실행하고 'Get Request Token' 버튼을 누르면 아래 이미지 처럼 인증을 요구하는 화면이 나오고 Allow 하고 나면,

    아래 이미지 처럼 PIN 번호가 보여진다.

  11. 이제 PIN 번호를 입력하고 'Get Access Token'을 클릭했을 때의 처리를 하면 된다. accessTokenButton: 메서드를 아래처럼 작성하고 accessTokenTicket:didFinishWithData:, accessTokenTicket:didFailWithError: 델리게이트 메서드도 만들자.

    - (IBAction)accessTokenButton:(UIButton *)sender { OAConsumer *consumer = [[OAConsumer alloc] initWithKey:@"Z0DxPl4q7kmSOgh3LTpV4Q" secret:@"LWryiOYBAHJ58PX9Yn1yG5bzDwpMJiksqpXxfst7kcU"]; NSURL *url = [[NSURL alloc] initWithString:@"http://twitter.com/oauth/access_token"]; OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url consumer:consumer token:self.requestToken realm:@"http://twitter.com/" signatureProvider:nil]; [request setOAuthParameterName:@"oauth_verifier" withValue:self.textField.text]; OADataFetcher *fetcher = [[OADataFetcher alloc] init]; [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(accessTokenTicket:didFinishWithData:) didFailSelector:@selector(accessTokenTicket:didFailWithError:)]; [consumer release]; [url release]; [request release]; [fetcher release]; } - (void)accessTokenTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { if (ticket.didSucceed) { NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; OAToken *token = [[OAToken alloc] initWithHTTPResponseBody:responseBody]; NSLog(@"Got Access Token [key:%@, secret:%@]", token.key, token.secret); [token release]; [responseBody release]; } else { NSLog(@"Finish but did not succeed."); } } - (void)accessTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error { NSLog(@"Error: %@", [error localizedDescription]); }

  12. 이제 실행해서 PIN 번호를 넣고 'Get Access Token' 버튼을 누르면 아래처럼 Access Token 정보가 콘솔에 출력된다.

    Got Access Token [key:14368376-CyPcPg7uVLcOkzRJBlJLMVKqZQMzCMQnRxHMmzQG8, secret:HY3eENZ6Pt4AFdUUtzAROlZDaKHOJHtcc7lMKMyKE]

  13. 이제 위에서 출력되는 Access Token 정보를 저장해서 OAMutableURLRequest 클래스로 요청 할 때 token 인자에 넣어 보내면 된다. 요청 할 때 파라미터를 세팅해야 할 경우에는, OARequestParameter 파라미터를 NSArray 로 묶어 OAMutableURLRequest 생성 후에 setParameter: 해주면 된다.

틀린 내용이 있다면 지적해주세요!

'컴퓨터 얘기 > 프로그래밍' 카테고리의 다른 글

iPhone 에서 OAuth 라이브러리 사용하기  (7) 2010/03/05
Read Me 플러그인  (3) 2007/12/07
드림위버와 이별하기  (5) 2007/11/28
MySQL Foreign Key 바보짓  (6) 2007/04/09
TinyMCE 플러그인 - WikiExporter  (5) 2007/02/07
멜론 앨범 커버 다운로더  (20) 2007/02/04