0

Play Video Youtube with XCDYouTubeKit and other quality

Hiện nay có khá nhiều lib để play video youtube nhưng theo đánh giá của các coder từ cộng đồng đánh giá thì XCDYouTubeKit là 1 lib khá là ngon lành. Hnay mình sẽ hướng dẫn các bạn làm demo app sử dụng XCDYouTubeKit và JASidePanels. Đây là sự kết hợp khá tốt giữa 2 thư viện này youtube1.png

Tiếp theo bạn tạo 1 filefile tên là Podfile để tạo file pod sử dựng trong dự án.

Sau đó chúng ta truy cập vào địa chỉ sau:

http://cocoapods.org/

Bạn vào ô tìm kiếm và gõ các từ khoá sau:

XCDYouTubeKit

JASidePanels

SDWebImage

Khi tìm kiếm sẽ có giao diện như sau:

youtube2.png

Bạn click vào nút copy to clip board, để copy đoạn lệnh cài đặt với cocoa pod và pasre vào file Podfile vừa tạo. Tương tự bạn cũng làm vậy với thư viện JASidePanels.

Nội dung của podfile sẽ như sau:

 platform :ios, '6.0'

pod 'SDWebImage', '~>3.6'
pod 'XCDYouTubeKit', '~> 2.0'
pod 'JASidePanels', '~> 1.3'

Tuỳ thêm mục đích sử dụng của các thánh mà có thể thêm các thư viện cần thiết. Tiếp theo bạn mở terminal và gõ CD và gõ đường dẫn đến thư mục đặt project, sau đó gõ lệnh:

pod install

youtube3.png

Sau đó bạn vào thư mục chứa project vừa tạo và mở file PlayVideoYoutubeDemo.xcworkspace. Từ đây chúng ta sẽ sử dụng file này thay cho file project cũ.

Để sử dụng JSPanel chúng ta cần tạo ra 3 class.

  • Class 1: MySidePanelController kế thừa từ class JASidePanelController của lib vừa download

  • Class 2: Thiết kế menu bên trái của màn hình kế thừa từ UIViewController

  • Class 3 Dùng để Hiện list video cần play

Do project này tôi sử dụng storyboad nên Class MySidePanelController cần thêm hàm sau :

-(void) awakeFromNib
{
    [self setLeftPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"LeftMenuController"]];
    [self setCenterPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"HomeController"]];
    [self setRightPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"BookmarksController"]];
}

Hàm này mục đích để điền dữ liệu cho việc hiển thị các class theo menuslide. Ở file AppDelegate chúng ta cần thêm thuộc tính như sau:

 //
//  AppDelegate.h
//  VideoYouTube
//
//  Created by doanhkisi on 12/15/14.
//  Copyright (c) 2014 doanhkisi. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "MySidePanelController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) MySidePanelController *slidePanelController;

@end

Ở file m chúng ta thêm đoạn lệnh sau:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    self.slidePanelController = [storyboard instantiateViewControllerWithIdentifier:@"MySidePanelController"];
    return YES;
}

OK. Vậy là chúng ta đã tạo ra 1 app có slide menu rồi. Giờ đến lúc chúng ta tiếp tục việc tạo ra list video và playvideo đó. Chúng ta cùng tạo ra list video nhé.List video gồm có

  • 1 label hiển thị label của video

  • 1 label hiển thị thời lượng video

  • 1 label hiển thị số ng đã xem

  • 1 ảnh đại diện video

Ở bài viết http://vietshare.vn/3051/ios-objective-c/Animation-and-NSAutolayout-ios-7-8.aspx tôi đã hướng dẫn các bạn dùng autolayout rồi, ở project này tôi ko nói lại phần thiết kế giao diện nữa. Ở đây chúng ta sẽ xây dựng giao diện như sau:

youtube4.png

Chạy lên thì sẽ giao diện nó sẽ ntn. Các thým lưu ý về việc sử dùng autolayout, cần phải loạ bỏ toàn bộ các warning về layout thì mới có thể pass qua được review của apple.

youtube5.png

- (void)fakeData {
    NSDictionary *dict1 =@{@"id":@1,@"name":@"Để tmai tính 2 - BTS Lên nóc nhà, nhảy qua phà", @"view":@100000, @"image":@"http://d-cache.microadinc.com/images/6591/1840200_1.jpg",@"link":@"DKaZtnJLSZ0", @"time":@1000};
    NSDictionary *dict2 =@{@"id":@2,@"name":@"One direction - Night changes (Behind)", @"view":@30000, @"image":@"http://www.thesaleslion.com/wp-content/uploads/2013/03/video.jpg", @"link":@"003LPzYwSNc",@"time":@300};
    NSDictionary *dict3 =@{@"id":@1,@"name":@"iPhone 6 và những thông tin mới được hé lộ trước giờ G", @"view":@100000, @"image":@"http://s107-haivainoi.cdn.vccloud.vn/images/2015/03/16/medium_xu39w1ayzsfkbk9dkd6bxzfdlfyuiwmetkh8etxgdqmsaknw21.jpg",@"link":@"8l8zSmg9alg"};
    NSDictionary *dict4 =@{@"id":@2,@"name":@"Lộ diện thiết kế đầy đủ của iPhone 6", @"view":@30000, @"image":@"http://didongthongminh.vn/images/tintuc/ADR_Iphone6_011_1.jpg", @"link":@"D-6JDufCJ1Y",@"time":@1000};
    NSDictionary *dict5 =@{@"id":@1,@"name":@"ĐThêm vào đó, nguồn tin trên cũng cho hay, mới đây, đội ngũ chăm sóc khách hàng ", @"view":@100000, @"image":@"http://ssisoft.com/Client/upload/News/User_1/2014/6/30/viral-real-estate-video.png",@"link":@"",@"time":@700};
    NSDictionary *dict6 =@{@"id":@2,@"name":@"ORumani đã tuyên bố hủy tất cả kỳ nghỉ phép của nhân viên", @"view":@30000, @"image":@"http://www.thesaleslion.com/wp-content/uploads/2013/03/video.jpg", @"link":@"",@"time":@1023};
    NSDictionary *dict7 =@{@"id":@1,@"name":@"Sau đây là loạt ảnh mới về model iPhone 6 sắp ra mắt:", @"view":@100000, @"image":@"http://didongthongminh.vn/images/image-1409898897-image-1408812027-825A7412-1160x773.jpg",@"link":@"",@"time":@2434};
    NSDictionary *dict8 =@{@"id":@2,@"name":@"Mới đây, xuất hiện 1 loạt ảnh về iPhone 6 sắp ra mắt, được đăng tải với đầy đủ thông tin", @"view":@30000, @"image":@"http://didongthongminh.vn/images/tintuc/ADR_Iphone6_011_1.jpg", @"link":@"",@"time":@1760};
    [dataSource addObject:dict1];
    [dataSource addObject:dict2];
    [dataSource addObject:dict3];
    [dataSource addObject:dict4];
    [dataSource addObject:dict5];
    [dataSource addObject:dict6];
    [dataSource addObject:dict7];
    [dataSource addObject:dict8];
}

Với UITableview bạn cần triển khai 2 phương thức:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return dataSource.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifer = @"Cell";
    ListVideoCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifer];
    if (!cell) {
        cell = [[ListVideoCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifer];
    }
    NSDictionary *dict = [dataSource objectAtIndex:indexPath.row];
    [cell.videoImageView sd_setImageWithURL:[NSURL URLWithString:[dict objectForKey:@"image"]] placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

    }];
    cell.videoNameLabel.text = [dict objectForKey:@"name"];
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init];
    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
    cell.countViewsLabel.text = [NSString stringWithFormat:@"%@ views",[formatter stringFromNumber:[dict objectForKey:@"view"]]];
    NSInteger totalTime = [[dict objectForKey:@"time"] integerValue];;
    NSInteger hour = totalTime/3600;
    NSInteger minute = totalTime/60;
    NSInteger second = totalTime%60;
    cell.timeLabel.text =[NSString stringWithFormat:@"%02ld:%02ld:%02ld",(long)hour, (long)minute, (long)second];
    cell.contentView.backgroundColor = [UIColor brownColor];
     return cell;
}

Nào giờ chúng ta bắt đầu vào việc playvideo trên youtube. Với thư viện chúng ta đang dùng, nó chỉ nhận videoIdentifer mà thôi. Với 1 đường link như như sau:

https://www.youtube.com/watch?v=mJDhX0-H8RE

Thì VideoIdentifer chính là đoạn cuối mJDhX0-H8RE.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSDictionary *dict = [dataSource objectAtIndex:indexPath.row];
    XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:[dict objectForKey:@"link"]];
    [self presentMoviePlayerViewControllerAnimated:videoPlayerViewController];
}

Nào cùng play và thưởng thức nào: youtube6.png

Với 1 video trên youtube thì sẽ có các độ phân giải khác nhau, mình muốn user có thể chọn loại độ phân giải thì sao. Khi đó ta phải dùng api của google để lấy.

[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:self.videoIdentifierTextField.text completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
		NSDictionary *dict = video.streamURLs;
		NSLog(@"xxx %@",dict);
	}];

XCDYouTubeClient sẽ giúp chúng ta lấy về danh sách các độ phân giải

134 = "http://r3---sn-42u-i5oe.googlevideo.com/videoplayback?source=youtube&initcwndbps=1497500&sparams=clen%2Cdur%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmm%2Cms%2Cmv%2Cpl%2Csource%2Cupn%2Cexpire&lmt=1424561135304972&ipbits=0&fexp=900720%2C907263%2C912525%2C934954%2C936109%2C9405136%2C9406837%2C9407103%2C9407663%2C9407852%2C9408101%2C9408206%2C942619%2C948124%2C948703%2C948822%2C950507%2C951511%2C951703%2C952612%2C957201%2C961404%2C961406&sver=3&clen=5441067&dur=880.800&key=yt5&mt=1427344031&mv=m&upn=bolCgbVTb60&ms=au&signature=2CCB83DDA095955A371CAF21F9703F8F8F187991.E9A0423714635A0826B6725397CB44C12BCBBD37&id=o-APyIzFyKHw4H8qqYHP1DZBbevsoU2uPBGnjP-uYzo48H&gir=yes&itag=134&ip=118.70.170.72&mm=31&expire=1427365692&pl=24";
    17 = "http://r3---sn-42u-i5oe.googlevideo.com/videoplayback?source=youtube&mt=1427344031&mv=m&upn=NLheue98UH8&ms=au&signature=6B8265FE1574D848EE9B5FB57C59072BD2E06440.83AAECEB8155536E7A3BF4C7E19959D8CBE8ED53&sver=3&id=o-APyIzFyKHw4H8qqYHP1DZBbevsoU2uPBGnjP-uYzo48H&fexp=900720%2C907263%2C912525%2C934954%2C936109%2C9405136%2C9406837%2C9407103%2C9407663%2C9407852%2C9408101%2C9408206%2C942619%2C948124%2C948703%2C948822%2C950507%2C951511%2C951703%2C952612%2C957201%2C961404%2C961406&sparams=dur%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Cmm%2Cms%2Cmv%2Cpl%2Csource%2Cupn%2Cexpire&initcwndbps=1497500&expire=1427365692&key=yt5&ip=118.70.170.72&mm=31&ipbits=0&dur=881.057&itag=17&pl=24";
    36 = "http://r3---sn-42u-i5oe.googlevideo.com/videoplayback?source=youtube&mt=1427344031&mv=m&upn=NLheue98UH8&ms=au&signature=400CCD4A4D489F38D3CB48F25621BD9B4B29988E.40040091E2207F198F24504E500557F6793894FA&sver=3&id=o-APyIzFyKHw4H8qqYHP1DZBbevsoU2uPBGnjP-uYzo48H&fexp=900720%2C907263%2C912525%2C934954%2C936109%2C9405136%2C9406837%2C9407103%2C9407663%2C9407852%2C9408101%2C9408206%2C942619%2C948124%2C948703%2C948822%2C950507%2C951511%2C951703%2C952612%2C957201%2C961404%2C961406&sparams=dur%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Cmm%2Cms%2Cmv%2Cpl%2Csource%2Cupn%2Cexpire&initcwndbps=1497500&expire=1427365692&key=yt5&ip=118.70.170.72&mm=31&ipbits=0&dur=881.057&itag=36&pl=24";
    243 = "http://r3---sn-42u-i5oe.googlevideo.com/videoplayback?source=youtube&initcwndbps=1497500&sparams=clen%2Cdur%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmm%2Cms%2Cmv%2Cpl%2Csource%2Cupn%2Cexpire&lmt=1410499362666587&ipbits=0&fexp=900720%2C907263%2C912525%2C934954%2C936109%2C9405136%2C9406837%2C9407103%2C9407663%2C9407852%2C9408101%2C9408206%2C942619%2C948124%2C948703%2C948822%2C950507%2C951511%2C951703%2C952612%2C957201%2C961404%2C961406&sver=3&clen=6640293&dur=880.767&key=yt5&mt=1427344031&mv=m&upn=bolCgbVTb60&ms=au&signature=68FE4FA1081F966B76E2A615301FF48DB7926462.DABCD39438FB47D14959D25902052BBB9E5021F1&id=o-APyIzFyKHw4H8qqYHP1DZBbevsoU2uPBGnjP-uYzo48H&gir=yes&itag=243&ip=118.70.170.72&mm=31&expire=1427365692&pl=24";

Ở đây mình chỉ demo 1 số đoạn respone nó trả về thôi, nhìn vào đây rối mắt quá. XCDYouTube đã định nghĩa sẵn cho chúng ta 1 số độ phân giải nhất định

typedef NS_ENUM(NSUInteger, XCDYouTubeVideoQuality) {
    /**
     *  Video: 240p MPEG-4 Visual | 0.175 Mbit/s
     *  Audio: AAC | 36 kbit/s
     */
    XCDYouTubeVideoQualitySmall240  = 36,

    /**
     *  Video: 360p H.264 | 0.5 Mbit/s
     *  Audio: AAC | 96 kbit/s
     */
    XCDYouTubeVideoQualityMedium360 = 18,

    /**
     *  Video: 720p H.264 | 2-3 Mbit/s
     *  Audio: AAC | 192 kbit/s
     */
    XCDYouTubeVideoQualityHD720     = 22
};

Để lựa chọn độ phân giải ta chỉ cần 1 đoạn code đơn giản

[[XCDYouTubeClient defaultClient] getVideoWithIdentifier:[dict objectForKey:@"link"] completionHandler:^(XCDYouTubeVideo *video, NSError *error) {
        NSDictionary *streamURLs = video.streamURLs;
        NSURL *url = streamURLs[@(XCDYouTubeVideoQualityHD720)] ?: streamURLs[@(XCDYouTubeVideoQualityMedium360)] ?: streamURLs[@(XCDYouTubeVideoQualitySmall240)];
    }];

Vâng việc lấy độ phân giải đơn giản là vậy thôi, đến đây tưởng chừng như rất đơn giản. Nhưng thật ra thì ko đơn giản chút nào đâu các thým ạh, vì cách này gọi đến api của thằng youtube, mà các thým apple lại rất ghét và reject thẳng tay với app của bạn(thế mới đen). Giờ cách giải quyết ra sao, mình cũng đã có giải pháp nhưng chưa biết thành công hay ko. Đó là đoạn code lấy độ phân giải ta làm sau khi apple đã review. Bạn cần 1 cái cờ để set trên sever, như vậy là ngon roài =))

link demo

https://github.com/doanhkisi/PlayvideoYoutubeDemo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí