Skip to content

Commit

Permalink
Merge branch 'release/2.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
0xced committed Feb 6, 2015
2 parents c973a56 + b8a2073 commit 1e4ab72
Show file tree
Hide file tree
Showing 46 changed files with 1,133 additions and 679 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#### Version 2.1.0

* New `expirationDate` property on the `XCDYouTubeVideo` class. (#96)
* Create proper (non generic) Xcode archives when integrated manually. (#102)
* Adaptation to YouTube API change. (#105)
* Fixed protected age restricted videos.

#### Version 2.0.3

* Adaptation to YouTube API change. (#94)
Expand Down
41 changes: 41 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## Submitting issues

* First of all, please [search](https://github.com/0xced/XCDYouTubeKit/issues) if your issue has already been filed.
* Read the [documentation](http://cocoadocs.org/docsets/XCDYouTubeKit/), the solution to your issue might be there.
* Make sure you are using the [latest version](https://github.com/0xced/XCDYouTubeKit/releases) of XCDYouTubeKit.
* State which version of XCDYouTubeKit you use in your report.
* State which version of the iOS or OS X SDK you use.
* State which device (or simulator) you use and the exact OS version in your report.
* If you encounter a crash, provide a stack trace. At the time of the crash, just type the `bt all` command in the (lldb) command prompt. If you got a crash report from HockeyApp or Crashlytics for example, include the stack trace too, preferably in textual form instead of a screenshot for easier searching.
* In your report, describe exactly
* **what you did**
* **what you expected**
* **what you observed**

---

Here is an example of a good bug report:

1. With the provided XCDYouTubeKit Demo app
2. Using XCDYouTubeKit 2.0.3 and iOS SDK 8.0
3. Running iPhone 4s simulator on iOS 7.1
4. In the *Full Screen Player* view of the demo app, I entered the video identifier `EdeVaT-zZt44` and pressed the *Play Full Screen* button. The *Low Quality* switch was off.
5. I expected the video *Better* from Apple to play.
6. Instead, the player closed immediately with the following log in the Xcode console:

```
2015-01-11 14:50:40.994 XCDYouTubeKit iOS Demo[67501:60b] Finish Reason: Playback Error
Error Domain=XCDYouTubeVideoErrorDomain Code=2 "Invalid parameters." UserInfo=0x7a6955a0 {NSURL=https://www.youtube.com/get_video_info?el=detailpage&hl=en&ps=default&video_id=EdeVaT-zZt44, NSLocalizedDescription=Invalid parameters.}
```

(The problem here is that the video identifier is invalid: `EdeVaT-zZt44` with an extra `4` instead of `EdeVaT-zZt4`)

---

If your problem can not be demonstrated with the demo app, please provide a test app yourself. A link to a zipped Xcode project is fine but a GitHub repository with your test app is even better. You don’t need to provide your whole app. Create a test app with the very minimum code required in order to exhibit your problem. During the process of reducing your test app to the minimum, you are very likely to find the solution to your problem by yourself, try it!

## Submitting pull requests

* Please try to follow the coding style of the project as much as you can.
* Unless your pull request is a trivial fix such as a typo, please make sure to have a unit test covering your changes.
* I am using git flow, so it means that the current development happens on the `develop` branch. Please submit your pull requests on the `develop` branch. See also the GitHub guide on [Forking Projects](https://guides.github.com/activities/forking/).
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[![Coverage Status](https://img.shields.io/coveralls/0xced/XCDYouTubeKit/master.svg?style=flat)](https://coveralls.io/r/0xced/XCDYouTubeKit?branch=master)
[![Platform](https://img.shields.io/cocoapods/p/XCDYouTubeKit.svg?style=flat)](http://cocoadocs.org/docsets/XCDYouTubeKit/)
[![Pod Version](https://img.shields.io/cocoapods/v/XCDYouTubeKit.svg?style=flat)](http://cocoadocs.org/docsets/XCDYouTubeKit/)
[![Carthage Compatibility](https://img.shields.io/badge/carthage-✓-f2a77e.svg?style=flat)](https://github.com/Carthage/Carthage/)
[![License](https://img.shields.io/cocoapods/l/XCDYouTubeKit.svg?style=flat)](LICENSE)

**XCDYouTubeKit** is a YouTube video player for iOS and OS X.
Expand All @@ -19,22 +20,22 @@ Are you enjoying XCDYouTubeKit? You can say thank you with [a tweet](https://twi
- Runs on iOS 5.0 and later
- Runs on OS X 10.7 and later

## Warnings
## Warning

* XCDYouTubeKit is against the YouTube [Terms of Service](https://www.youtube.com/t/terms). The only *official* way of playing a YouTube video inside an app is with a web view and the [iframe player API](https://developers.google.com/youtube/iframe_api_reference). Unfortunately, this is very slow and quite ugly, so I wrote this player to give users a better viewing experience.

* Except for live videos, the player uses progressive download. Remember that some restrictions apply if you submit your app to the App Store, as stated in
[HTTP Live Streaming — Requirements for Apps](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/UsingHTTPLiveStreaming/UsingHTTPLiveStreaming.html#//apple_ref/doc/uid/TP40008332-CH102-SW5):
> **Warning**: iOS apps submitted for distribution in the App Store must conform to these requirements.
>
> If your app delivers video over cellular networks, and the video exceeds either 10 minutes duration or 5 MB of data in a five minute period, you are required to use HTTP Live Streaming. (Progressive download may be used for smaller clips.)
XCDYouTubeKit is against the YouTube [Terms of Service](https://www.youtube.com/t/terms). The only *official* way of playing a YouTube video inside an app is with a web view and the [iframe player API](https://developers.google.com/youtube/iframe_api_reference). Unfortunately, this is very slow and quite ugly, so I wrote this player to give users a better viewing experience.

## Installation

XCDYouTubeKit is available through CocoaPods.
XCDYouTubeKit is available through CocoaPods and Carthage.

CocoaPods:
```ruby
pod "XCDYouTubeKit", "~> 2.0.3"
pod "XCDYouTubeKit", "~> 2.1.0"
```

Carthage:
```objc
github "0xced/XCDYouTubeKit" ~> 2.1.0
```

Alternatively, you can manually use the provided static library on iOS or dynamic framework on OS X. In order to use the iOS static library, you must:
Expand Down
2 changes: 1 addition & 1 deletion Scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ set -v
sed -i "" "s/DYLIB_CURRENT_VERSION = .*;/DYLIB_CURRENT_VERSION = ${VERSION};/g" "XCDYouTubeKit.xcodeproj/project.pbxproj"
sed -i "" "s/CURRENT_PROJECT_VERSION = .*;/CURRENT_PROJECT_VERSION = ${VERSION};/g" "XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj/project.pbxproj"
sed -i "" "s/^\(.*s.version.*=.*\)\".*\"/\1\"${VERSION}\"/" "XCDYouTubeKit.podspec"
sed -i "" "s/\"~> .*\"/\"~> ${VERSION}\"/g" "README.md"
sed -E -i "" "s/~> [0-9\.]+/~> ${VERSION}/g" "README.md"
set +v
git add "XCDYouTubeKit.xcodeproj"
git add "XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj"
Expand Down
10 changes: 8 additions & 2 deletions XCDYouTubeKit Demo/XCDYouTubeKit Demo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
C27415E517F4D0330026834B /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C27415E417F4D0330026834B /* MediaPlayer.framework */; };
C27AD2A11A0791F000866050 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C27AD2A01A0791F000866050 /* Images.xcassets */; };
C2BA376D192AB32200B27FAD /* MPMoviePlayerController+BackgroundPlayback.m in Sources */ = {isa = PBXBuildFile; fileRef = C2BA376C192AB32200B27FAD /* MPMoviePlayerController+BackgroundPlayback.m */; };
C2C5D2981A6E5AB900F2B3F8 /* VideoPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = C2C5D2971A6E5AB900F2B3F8 /* VideoPickerController.m */; };
C2DDFAF419C2CEB000E7DB66 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = C2DDFAF319C2CEB000E7DB66 /* LaunchScreen.xib */; };
C2EFB48718730A2B0046B1FE /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C2EFB48618730A2B0046B1FE /* SettingsViewController.m */; };
C2F0E59F1945065C00D8EBA8 /* XCDYouTubeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2F0E59E1945065C00D8EBA8 /* XCDYouTubeKit.framework */; };
Expand Down Expand Up @@ -100,6 +101,8 @@
C27AD2A01A0791F000866050 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
C2BA376B192AB32200B27FAD /* MPMoviePlayerController+BackgroundPlayback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MPMoviePlayerController+BackgroundPlayback.h"; sourceTree = "<group>"; };
C2BA376C192AB32200B27FAD /* MPMoviePlayerController+BackgroundPlayback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPMoviePlayerController+BackgroundPlayback.m"; sourceTree = "<group>"; };
C2C5D2961A6E5AB900F2B3F8 /* VideoPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoPickerController.h; sourceTree = "<group>"; };
C2C5D2971A6E5AB900F2B3F8 /* VideoPickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoPickerController.m; sourceTree = "<group>"; };
C2DDFAF319C2CEB000E7DB66 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = "<group>"; };
C2EDD2EC1805917900BEA32B /* libXCDYouTubeKit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libXCDYouTubeKit.a; sourceTree = BUILT_PRODUCTS_DIR; };
C2EFB48518730A2B0046B1FE /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -207,6 +210,8 @@
C2570B851A02415F00127127 /* NowPlayingInfoCenterProvider.m */,
C27415C317F4CDD80026834B /* DemoFullScreenViewController.h */,
C27415C417F4CDD80026834B /* DemoFullScreenViewController.m */,
C2C5D2961A6E5AB900F2B3F8 /* VideoPickerController.h */,
C2C5D2971A6E5AB900F2B3F8 /* VideoPickerController.m */,
C27415C517F4CDD80026834B /* DemoInlineViewController.h */,
C27415C617F4CDD80026834B /* DemoInlineViewController.m */,
C27415C717F4CDD80026834B /* DemoThumbnailViewController.h */,
Expand Down Expand Up @@ -343,6 +348,7 @@
C27415D317F4CDD80026834B /* DemoAsynchronousViewController.m in Sources */,
C2630D3F1935C449000D3917 /* PlayerEventLogger.m in Sources */,
C27415D417F4CDD80026834B /* DemoFullScreenViewController.m in Sources */,
C2C5D2981A6E5AB900F2B3F8 /* VideoPickerController.m in Sources */,
C27415D517F4CDD80026834B /* DemoInlineViewController.m in Sources */,
C27415D617F4CDD80026834B /* DemoThumbnailViewController.m in Sources */,
C27415DC17F4CDD80026834B /* main.m in Sources */,
Expand Down Expand Up @@ -451,7 +457,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 2.0.3;
CURRENT_PROJECT_VERSION = 2.1.0;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
Expand Down Expand Up @@ -485,7 +491,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 2.0.3;
CURRENT_PROJECT_VERSION = 2.1.0;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PREPROCESSOR_DEFINITIONS = "NS_BLOCK_ASSERTIONS=1";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
Expand Down
4 changes: 3 additions & 1 deletion XCDYouTubeKit Demo/iOS Demo/DemoFullScreenViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Copyright (c) 2013-2014 Cédric Luthi. All rights reserved.
//

@interface DemoFullScreenViewController : UIViewController <UITextFieldDelegate>
#import "VideoPickerController.h"

@interface DemoFullScreenViewController : UIViewController <UITextFieldDelegate, VideoPickerControllerDelegate>

@property (nonatomic, weak) IBOutlet UITextField *videoIdentifierTextField;
@property (nonatomic, weak) IBOutlet UISwitch *lowQualitySwitch;
Expand Down
43 changes: 39 additions & 4 deletions XCDYouTubeKit Demo/iOS Demo/DemoFullScreenViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,51 @@ - (void) viewDidLoad
{
[super viewDidLoad];

[self restoreVideoIdentifier];
}

- (void) saveVideoIdentifier
{
[[NSUserDefaults standardUserDefaults] setObject:self.videoIdentifierTextField.text forKey:@"VideoIdentifier"];
}

- (void) restoreVideoIdentifier
{
self.videoIdentifierTextField.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"VideoIdentifier"];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (IBAction) endEditing:(id)sender
{
[self.view endEditing:YES];
}

- (IBAction) play:(id)sender
{
[self.view endEditing:YES];

XCDYouTubeVideoPlayerViewController *videoPlayerViewController = [[XCDYouTubeVideoPlayerViewController alloc] initWithVideoIdentifier:self.videoIdentifierTextField.text];
videoPlayerViewController.moviePlayer.backgroundPlaybackEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"PlayVideoInBackground"];
videoPlayerViewController.preferredVideoQualities = self.lowQualitySwitch.on ? @[ @(XCDYouTubeVideoQualitySmall240), @(XCDYouTubeVideoQualityMedium360) ] : nil;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerPlaybackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:videoPlayerViewController.moviePlayer];
[self presentMoviePlayerViewControllerAnimated:videoPlayerViewController];
}

#pragma mark - Notifications

- (void) moviePlayerPlaybackDidFinish:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:notification.object];
MPMovieFinishReason finishReason = [notification.userInfo[MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] integerValue];
if (finishReason == MPMovieFinishReasonPlaybackError)
{
NSString *title = NSLocalizedString(@"Video Playback Error", @"Full screen video error alert - title");
NSError *error = notification.userInfo[XCDMoviePlayerPlaybackDidFinishErrorUserInfoKey];
NSString *message = [NSString stringWithFormat:@"%@\n%@ (%@)", error.localizedDescription, error.domain, @(error.code)];
NSString *cancelButtonTitle = NSLocalizedString(@"OK", @"Full screen video error alert - cancel button");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil];
[alertView show];
}
}


#pragma mark - UITextFieldDelegate

- (BOOL) textFieldShouldReturn:(UITextField *)textField
Expand All @@ -38,7 +65,15 @@ - (BOOL) textFieldShouldReturn:(UITextField *)textField

- (void) textFieldDidEndEditing:(UITextField *)textField
{
[[NSUserDefaults standardUserDefaults] setObject:textField.text forKey:@"VideoIdentifier"];
[self saveVideoIdentifier];
}

#pragma mark - VideoPickerControllerDelegate

- (void) videoPickerController:(VideoPickerController *)videoPickerController didSelectVideoWithIdentifier:(NSString *)videoIdentifier
{
self.videoIdentifierTextField.text = videoIdentifier;
[self saveVideoIdentifier];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ + (void) load
});
}

static void *BackgroundPlaybackEnabledKey = &BackgroundPlaybackEnabledKey;
static const void * const BackgroundPlaybackEnabledKey = &BackgroundPlaybackEnabledKey;

- (BOOL) isBackgroundPlaybackEnabled
{
Expand Down Expand Up @@ -89,7 +89,7 @@ + (void) backgroundPlayback_moviePlayerPlaybackDidFinish:(NSNotification *)notif
return playerLayer;
}

static void *PlayerKey = &PlayerKey;
static const void * const PlayerKey = &PlayerKey;

+ (void) backgroundPlayback_applicationWillResignActive:(NSNotification *)notification
{
Expand All @@ -110,7 +110,9 @@ + (void) backgroundPlayback_applicationWillResignActive:(NSNotification *)notifi
+ (void) backgroundPlayback_applicationDidBecomeActive:(NSNotification *)notification
{
AVPlayerLayer *playerLayer = PlayerLayer();
playerLayer.player = objc_getAssociatedObject(currentMoviePlayerController, PlayerKey);
AVPlayer *player = objc_getAssociatedObject(currentMoviePlayerController, PlayerKey);
if (player)
playerLayer.player = player;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,48 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>YouTubeDemoVideos</key>
<array>
<dict>
<key>Standard</key>
<string>EdeVaT-zZt4</string>
</dict>
<dict>
<key>VEVO</key>
<string>rId6PKlDXeU</string>
</dict>
<dict>
<key>Age Restricted</key>
<string>zKovmts2KSk</string>
</dict>
<dict>
<key>VEVO + Age Restricted</key>
<string>07FYdnEawAQ</string>
</dict>
<dict>
<key>Mobile Restricted</key>
<string>JHaA9bKi-xs</string>
</dict>
<dict>
<key>Live Video</key>
<string>i2-MnWWoL6M</string>
</dict>
<dict>
<key>DVR Video</key>
<string>H7iQ4sAf0OE</string>
</dict>
<dict>
<key>Restricted Video</key>
<string>1kIsylLeHHU</string>
</dict>
<dict>
<key>Removed Video</key>
<string>BXnA9FjvLSU</string>
</dict>
<dict>
<key>Geo-Blocked Video</key>
<string>vwkFTztnl7Y</string>
</dict>
</array>
</dict>
</plist>
30 changes: 30 additions & 0 deletions XCDYouTubeKit Demo/iOS Demo/VideoPickerController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// VideoPickerController.h
// XCDYouTubeKit Demo
//
// Created by Cédric Luthi on 20.01.15.
// Copyright (c) 2015 Cédric Luthi. All rights reserved.
//

#import <Foundation/Foundation.h>

@class VideoPickerController;

@protocol VideoPickerControllerDelegate <NSObject>
@optional
- (void) videoPickerController:(VideoPickerController *)videoPickerController didSelectVideoWithIdentifier:(NSString *)videoIdentifier;
@end

@interface VideoPickerController : NSObject <UIPickerViewDataSource, UIPickerViewDelegate>

@property (nonatomic, copy) NSArray *videos;

@property (nonatomic, weak) IBOutlet id<VideoPickerControllerDelegate> delegate;

@property (nonatomic, weak) IBOutlet UIPickerView *pickerView;

- (IBAction) togglePickerView:(id)sender;
- (IBAction) showPickerView:(id)sender;
- (IBAction) hidePickerView:(id)sender;

@end
Loading

0 comments on commit 1e4ab72

Please sign in to comment.