-
-
Notifications
You must be signed in to change notification settings - Fork 278
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding new use case of CircularSlider (Player)
- Loading branch information
Hamza GHAZOUANI
committed
Nov 9, 2016
1 parent
4f28865
commit 501f050
Showing
6 changed files
with
325 additions
and
60 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// | ||
// PlayerViewController.swift | ||
// HGCircularSlider | ||
// | ||
// Created by Hamza Ghazouani on 08/11/2016. | ||
// Copyright © 2016 CocoaPods. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
import AVFoundation | ||
|
||
import HGCircularSlider | ||
|
||
/* | ||
KVO context used to differentiate KVO callbacks for this class versus other | ||
classes in its class hierarchy. | ||
*/ | ||
private var playerViewControllerKVOContext = 0 | ||
|
||
|
||
class PlayerViewController: UIViewController { | ||
|
||
@IBOutlet weak var circularSlider: CircularSlider! | ||
@IBOutlet weak var timerLabel: UILabel! | ||
@IBOutlet weak var playerSegmentedControl: UISegmentedControl! | ||
|
||
let audioPlayer = AVPlayer() | ||
|
||
// date formatter user for timer label | ||
let dateComponentsFormatter: NSDateComponentsFormatter = { | ||
let formatter = NSDateComponentsFormatter() | ||
formatter.zeroFormattingBehavior = .Pad | ||
formatter.allowedUnits = [.Minute, .Second] | ||
|
||
return formatter | ||
}() | ||
|
||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
|
||
setupAudioPlayer() | ||
|
||
circularSlider.addTarget(self, action: #selector(pause), forControlEvents: .EditingDidBegin) | ||
circularSlider.addTarget(self, action: #selector(play), forControlEvents: .EditingDidEnd) | ||
circularSlider.addTarget(self, action: #selector(updateTimer), forControlEvents: .ValueChanged) | ||
|
||
NSNotificationCenter.defaultCenter().addObserver(self, | ||
selector: #selector(playerItemDidReachEnd(_:)), | ||
name: AVPlayerItemDidPlayToEndTimeNotification, | ||
object: audioPlayer.currentItem) | ||
} | ||
|
||
override func didReceiveMemoryWarning() { | ||
super.didReceiveMemoryWarning() | ||
// Dispose of any resources that can be recreated. | ||
} | ||
|
||
@IBAction func togglePlayer(sender: UISegmentedControl) { | ||
switch sender.selectedSegmentIndex { | ||
case 0: | ||
let currentTime = Float64(circularSlider.endPointValue) | ||
let newTime = CMTimeMakeWithSeconds(currentTime, 600) | ||
audioPlayer.seekToTime(newTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) | ||
audioPlayer.play() | ||
default: | ||
audioPlayer.pause() | ||
} | ||
} | ||
|
||
func play() { | ||
self.playerSegmentedControl.selectedSegmentIndex = 0 | ||
togglePlayer(playerSegmentedControl) | ||
} | ||
|
||
func pause() { | ||
self.playerSegmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment | ||
togglePlayer(playerSegmentedControl) | ||
} | ||
|
||
|
||
/** | ||
setup and play the sound of the local mp3 file | ||
*/ | ||
func setupAudioPlayer() { | ||
// TODO: load the audio file asynchronously and observe player status | ||
guard let audioFileURL = NSBundle.mainBundle().URLForResource("StrangeZero", withExtension: "mp3") else { return } | ||
let asset = AVURLAsset(URL: audioFileURL, options: nil) | ||
let playerItem = AVPlayerItem(asset: asset) | ||
audioPlayer.replaceCurrentItemWithPlayerItem(playerItem) | ||
audioPlayer.actionAtItemEnd = .Pause | ||
|
||
let durationInSeconds = CMTimeGetSeconds(asset.duration) | ||
circularSlider.maximumValue = CGFloat(durationInSeconds) | ||
let interval = CMTimeMake(1, 4) | ||
audioPlayer.addPeriodicTimeObserverForInterval(interval, queue: dispatch_get_main_queue()) { | ||
[weak self] time in | ||
let seconds = CMTimeGetSeconds(time) | ||
self?.updatePlayerUI(withCurrentTime: CGFloat(seconds)) | ||
} | ||
|
||
self.audioPlayer.play() | ||
} | ||
|
||
|
||
// update the slider position and the timer text | ||
func updatePlayerUI(withCurrentTime currentTime: CGFloat) { | ||
circularSlider.endPointValue = currentTime | ||
let components = NSDateComponents() | ||
components.second = Int(currentTime) | ||
timerLabel.text = dateComponentsFormatter.stringFromDateComponents(components) | ||
} | ||
|
||
func updateTimer() { | ||
let components = NSDateComponents() | ||
components.second = Int(circularSlider.endPointValue) | ||
timerLabel.text = dateComponentsFormatter.stringFromDateComponents(components) | ||
} | ||
|
||
// MARK: - Notification | ||
|
||
func playerItemDidReachEnd(notification: NSNotification) { | ||
if let playerItem: AVPlayerItem = notification.object as? AVPlayerItem { | ||
playerItem.seekToTime(kCMTimeZero) | ||
playerSegmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment | ||
} | ||
} | ||
|
||
/* | ||
// MARK: - Navigation | ||
// In a storyboard-based application, you will often want to do a little preparation before navigation | ||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { | ||
// Get the new view controller using segue.destinationViewController. | ||
// Pass the selected object to the new view controller. | ||
} | ||
*/ | ||
} |
Binary file not shown.
40 changes: 20 additions & 20 deletions
40
Example/Pods/Target Support Files/Pods-HGCircularSlider_Tests/Info.plist
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters