aboutsummaryrefslogtreecommitdiffstats
path: root/Video Tuneup
diff options
context:
space:
mode:
Diffstat (limited to 'Video Tuneup')
-rw-r--r--Video Tuneup/ViewController.h14
-rw-r--r--Video Tuneup/ViewController.m168
-rw-r--r--Video Tuneup/en.lproj/ViewController_iPad.xib58
3 files changed, 230 insertions, 10 deletions
diff --git a/Video Tuneup/ViewController.h b/Video Tuneup/ViewController.h
index 99a7a1b..8c84b4f 100644
--- a/Video Tuneup/ViewController.h
+++ b/Video Tuneup/ViewController.h
@@ -16,6 +16,11 @@
@interface ViewController : UIViewController {
AVURLAsset *asset;
AVURLAsset *songAsset;
+
+ // Related to scrubbing
+ float mRestoreAfterScrubbingRate;
+ BOOL seekToZeroBeforePlay;
+ id mTimeObserver;
}
@property (nonatomic, retain) AVPlayer *player;
@@ -27,6 +32,8 @@
@property (nonatomic, retain) IBOutlet UIButton *rewindButton;
@property (nonatomic, retain) IBOutlet UIToolbar *videoNavBar;
@property (nonatomic, retain) IBOutlet UILabel *exportStatus;
+@property (nonatomic, retain) IBOutlet UISlider* mScrubber;
+
- (void)hideCameraRollText;
- (IBAction)loadAssetFromFile:sender;
@@ -36,6 +43,13 @@
- (IBAction)rewind:sender;
- (IBAction)exportToCameraRoll:sender;
- (void)syncUI;
+- (void)syncScrubber;
+- (void)beginScrubbing:(id)sender;
+- (void)scrub:(id)sender;
+- (void)endScrubbing:(id)sender;
+- (BOOL)isScrubbing;
+- (void)initScrubberTimer;
+- (CMTime)playerItemDuration;
- (void)exportDidFinish:(AVAssetExportSession*)session;
@end \ No newline at end of file
diff --git a/Video Tuneup/ViewController.m b/Video Tuneup/ViewController.m
index 4fc5a99..83a82a9 100644
--- a/Video Tuneup/ViewController.m
+++ b/Video Tuneup/ViewController.m
@@ -15,7 +15,8 @@ static const NSString *ItemStatusContext;
@implementation ViewController
-@synthesize player, playerItem, playerView, playButton, pauseButton, rewindButton, editor, videoNavBar, exportStatus;
+@synthesize player, playerItem, playerView, playButton, pauseButton, rewindButton, editor, videoNavBar, exportStatus,
+mScrubber;
#pragma mark - Video playback
@@ -26,6 +27,7 @@ static const NSString *ItemStatusContext;
([player.currentItem status] == AVPlayerItemStatusReadyToPlay &&
CMTimeCompare([player.currentItem duration], kCMTimeZero) != 0)) {
playButton.enabled = YES;
+
NSLog(@"Enabling play button");
}
else {
@@ -35,13 +37,18 @@ static const NSString *ItemStatusContext;
}
- (void)refreshEditor {
- // Update assets
+ NSLog(@"Refreshing editor");
+
+ // Update editor assets
if (asset)
self.editor.video = asset;
if (songAsset)
self.editor.song = songAsset;
- // Begin export
+ // Remove old player
+ [self.player pause];
+
+ // Build composition for playback
[self.editor buildNewCompositionForPlayback:YES];
// Initialize editor's player
@@ -127,18 +134,20 @@ static const NSString *ItemStatusContext;
CMTimeCompare([player.currentItem duration], kCMTimeZero) != 0)) { // Paused
NSLog(@"Playing item");
[player play];
+ [self initScrubberTimer];
[self.videoNavBar setItems:[NSArray
arrayWithObjects:[self.videoNavBar.items objectAtIndex:0],
[self.videoNavBar.items objectAtIndex:1],
[self.videoNavBar.items objectAtIndex:2],
- [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPause target:self action:@selector(play:)],nil] animated:NO];
+ [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPause target:self action:@selector(play:)],[self.videoNavBar.items objectAtIndex:4],[self.videoNavBar.items objectAtIndex:5],nil] animated:NO];
} else {
[player pause];
[self.videoNavBar setItems:[NSArray arrayWithObjects:[self.videoNavBar.items objectAtIndex:0],
[self.videoNavBar.items objectAtIndex:1],
[self.videoNavBar.items objectAtIndex:2],
- [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(play:)],nil] animated:NO];
+ [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(play:)],[self.videoNavBar.items objectAtIndex:4],
+ [self.videoNavBar.items objectAtIndex:5], nil] animated:NO];
}
}
@@ -152,6 +161,154 @@ static const NSString *ItemStatusContext;
[player seekToTime:kCMTimeZero];
}
+
+// Handle scrubbing
+// Based on sample code from http://developer.apple.com/library/ios/#samplecode/AVPlayerDemo/Listings/Classes_AVPlayerDemoPlaybackViewController_m.html#//apple_ref/doc/uid/DTS40010101-Classes_AVPlayerDemoPlaybackViewController_m-DontLinkElementID_8
+
+#pragma mark -
+#pragma mark Movie scrubber control
+
+/* ---------------------------------------------------------
+ ** Methods to handle manipulation of the movie scrubber control
+ ** ------------------------------------------------------- */
+
+- (CMTime)playerItemDuration
+{
+ return [playerItem duration];
+}
+
+/* Requests invocation of a given block during media playback to update the movie scrubber control. */
+-(void)initScrubberTimer
+{
+ double interval = .1f;
+
+ CMTime playerDuration = [self playerItemDuration];
+ if (CMTIME_IS_INVALID(playerDuration))
+ {
+ return;
+ }
+ double duration = CMTimeGetSeconds(playerDuration);
+ if (isfinite(duration))
+ {
+ CGFloat width = CGRectGetWidth([mScrubber bounds]);
+ interval = 0.5f * duration / width;
+ }
+
+ /* Update the scrubber during normal playback. */
+ mTimeObserver = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
+ queue:NULL /* If you pass NULL, the main queue is used. */
+ usingBlock:^(CMTime time)
+ {
+ [self syncScrubber];
+ }];
+
+}
+
+/* Set the scrubber based on the player current time. */
+- (void)syncScrubber
+{
+ CMTime playerDuration = [self playerItemDuration];
+ if (CMTIME_IS_INVALID(playerDuration))
+ {
+ mScrubber.minimumValue = 0.0;
+ return;
+ }
+
+ double duration = CMTimeGetSeconds(playerDuration);
+ if (isfinite(duration))
+ {
+ float minValue = [mScrubber minimumValue];
+ float maxValue = [mScrubber maximumValue];
+ double time = CMTimeGetSeconds([player currentTime]);
+
+ [mScrubber setValue:(maxValue - minValue) * time / duration + minValue];
+ }
+}
+
+/* The user is dragging the movie controller thumb to scrub through the movie. */
+- (IBAction)beginScrubbing:(id)sender
+{
+ mRestoreAfterScrubbingRate = [player rate];
+ [player setRate:0.f];
+
+ /* Remove previous timer. */
+// [self removePlayerTimeObserver];
+}
+
+/* Set the player current time to match the scrubber position. */
+- (IBAction)scrub:(id)sender
+{
+ if ([sender isKindOfClass:[UISlider class]])
+ {
+ UISlider* slider = sender;
+
+ CMTime playerDuration = [self playerItemDuration];
+ if (CMTIME_IS_INVALID(playerDuration)) {
+ return;
+ }
+
+ double duration = CMTimeGetSeconds(playerDuration);
+ if (isfinite(duration))
+ {
+ float minValue = [slider minimumValue];
+ float maxValue = [slider maximumValue];
+ float value = [slider value];
+
+ double time = duration * (value - minValue) / (maxValue - minValue);
+
+ [player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)];
+ }
+ }
+}
+
+/* The user has released the movie thumb control to stop scrubbing through the movie. */
+- (IBAction)endScrubbing:(id)sender
+{
+ if (!mTimeObserver)
+ {
+ CMTime playerDuration = [self playerItemDuration];
+ if (CMTIME_IS_INVALID(playerDuration))
+ {
+ return;
+ }
+
+ double duration = CMTimeGetSeconds(playerDuration);
+ if (isfinite(duration))
+ {
+ CGFloat width = CGRectGetWidth([mScrubber bounds]);
+ double tolerance = 0.5f * duration / width;
+
+ mTimeObserver = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(tolerance, NSEC_PER_SEC) queue:NULL usingBlock:
+ ^(CMTime time)
+ {
+ [self syncScrubber];
+ }];
+ }
+ }
+
+ if (mRestoreAfterScrubbingRate)
+ {
+ [player setRate:mRestoreAfterScrubbingRate];
+ mRestoreAfterScrubbingRate = 0.f;
+ }
+}
+
+- (BOOL)isScrubbing
+{
+ return mRestoreAfterScrubbingRate != 0.f;
+}
+
+-(void)enableScrubber
+{
+ self.mScrubber.enabled = YES;
+}
+
+-(void)disableScrubber
+{
+ self.mScrubber.enabled = NO;
+}
+
+
- (IBAction)exportToCameraRoll:(id)sender {
NSLog(@"Editing...");
@@ -238,6 +395,7 @@ static const NSString *ItemStatusContext;
- (void)playerItemDidReachEnd:(NSNotification *)notification {
[player seekToTime:kCMTimeZero];
+ [player play]; // loop player. If not doing this, set button to pause
}
diff --git a/Video Tuneup/en.lproj/ViewController_iPad.xib b/Video Tuneup/en.lproj/ViewController_iPad.xib
index bcd19c2..d4cece4 100644
--- a/Video Tuneup/en.lproj/ViewController_iPad.xib
+++ b/Video Tuneup/en.lproj/ViewController_iPad.xib
@@ -2,10 +2,10 @@
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1280</int>
- <string key="IBDocument.SystemVersion">11C74</string>
+ <string key="IBDocument.SystemVersion">11D50d</string>
<string key="IBDocument.InterfaceBuilderVersion">1938</string>
- <string key="IBDocument.AppKitVersion">1138.23</string>
- <string key="IBDocument.HIToolboxVersion">567.00</string>
+ <string key="IBDocument.AppKitVersion">1138.32</string>
+ <string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">933</string>
@@ -117,7 +117,6 @@
<string key="targetRuntimeIdentifier">IBIPadFramework</string>
<int key="IBUIContentHorizontalAlignment">0</int>
<int key="IBUIContentVerticalAlignment">0</int>
- <float key="IBUIValue">0.5</float>
</object>
</array>
<string key="NSFrame">{{0, 587}, {671, 44}}</string>
@@ -318,6 +317,14 @@
<int key="connectionID">44</int>
</object>
<object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">mScrubber</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="119532371"/>
+ </object>
+ <int key="connectionID">51</int>
+ </object>
+ <object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">loadAssetFromFile:</string>
<reference key="source" ref="1049445720"/>
@@ -345,6 +352,42 @@
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">beginScrubbing:</string>
+ <reference key="source" ref="119532371"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">1</int>
+ </object>
+ <int key="connectionID">55</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">endScrubbing:</string>
+ <reference key="source" ref="119532371"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">7</int>
+ </object>
+ <int key="connectionID">56</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">endScrubbing:</string>
+ <reference key="source" ref="119532371"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">8</int>
+ </object>
+ <int key="connectionID">57</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
+ <string key="label">scrub:</string>
+ <reference key="source" ref="119532371"/>
+ <reference key="destination" ref="841351856"/>
+ <int key="IBEventType">13</int>
+ </object>
+ <int key="connectionID">58</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">exportToCameraRoll:</string>
<reference key="source" ref="806269495"/>
<reference key="destination" ref="841351856"/>
@@ -504,7 +547,7 @@
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
- <int key="maxID">49</int>
+ <int key="maxID">58</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -555,6 +598,7 @@
</dictionary>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="exportStatus">UILabel</string>
+ <string key="mScrubber">UISlider</string>
<string key="pauseButton">UIButton</string>
<string key="playButton">UIButton</string>
<string key="playerView">PlayerView</string>
@@ -566,6 +610,10 @@
<string key="name">exportStatus</string>
<string key="candidateClassName">UILabel</string>
</object>
+ <object class="IBToOneOutletInfo" key="mScrubber">
+ <string key="name">mScrubber</string>
+ <string key="candidateClassName">UISlider</string>
+ </object>
<object class="IBToOneOutletInfo" key="pauseButton">
<string key="name">pauseButton</string>
<string key="candidateClassName">UIButton</string>