Swipeable video filter in video playback - ios

I am using the pod SCRecorder, and I am trying to playback a recorded video in a separate view controller. I have no issue recording the video however when I initialize the videoPlayer view controller I get a blank screen. I was just wondering if anyone who has used the pod has any experience with this and could provide insight? Here is the code below:
RecorderViewController:
#IBOutlet weak var previewView: UIView!
#IBOutlet weak var recordButton: UIButton!
let session = SCRecordSession()
let recorder = SCRecorder()
var exportSession = SCAssetExportSession()
var photoOutput: AVCaptureStillImageOutput?
var photo: UIImage?
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
override func viewDidLoad() {
super.viewDidLoad()
self.recorder.captureSessionPreset = SCRecorderTools.bestCaptureSessionPresetCompatibleWithAllDevices()
if (!recorder.startRunning()) {
debugPrint("Recorder error: ", recorder.error)
}
recorder.session = session
recorder.device = AVCaptureDevicePosition.Back
recorder.videoConfiguration.size = CGSizeMake(screenWidth, screenHeight)
recorder.delegate = self
}
func capturePhoto(image: UIImage) {
var connection = photoOutput!.connectionWithMediaType(AVMediaTypeVideo)
photoOutput!.captureStillImageAsynchronouslyFromConnection(photoOutput!.connectionWithMediaType(AVMediaTypeVideo)) {
(imageDataSampleBuffer: CMSampleBuffer!, error: NSError!) in
if error == nil {
let data:NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
let image:UIImage = UIImage( data: data)!
//add showPhoto call so that functions won't have to be called and can be called from one central place
// BY 8PM TONIGHT APP SHOULD BE FINISHED!!!!!!!!!!!!!!!
} else{
print("Error")
}
}
}
func showPhoto(photo: UIImage) {
self.photo = photo
self.performSegueWithIdentifier("Photo", sender: self)
}
#IBAction func recordButtonTapped(sender: UIButton) {
recorder.record()
if recorder.isRecording{
print("video is recording")
}
}
func showVideo() {
self.performSegueWithIdentifier("Video", sender: self)
}
#IBAction func stopTapped(sender: UIButton) {
print("video was paused")
recorder.pause()
self.showVideo()
}
override func viewWillLayoutSubviews() {
}
override func viewDidLayoutSubviews()
{
recorder.previewView = previewView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
PlayerController:
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// Custom initialization
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
var player : SCPlayer?
self.filterView.removeObserver(self, forKeyPath: "selectedFilter")
self.filterView = nil
self.player.pause()
player = nil
}
let player = SCPlayer()
let session = SCRecordSession()
#IBOutlet weak var filterView: SCSwipeableFilterView!
override func viewWillAppear(animated: Bool) {
player.setItemByAsset(session.assetRepresentingSegments())
let playerLayer = AVPlayerLayer(player: player)
filterView.frame = self.view.bounds
filterView.layer.addSublayer(playerLayer)
self.filterView.contentMode = .ScaleAspectFill
player.play()
}
override func viewDidLoad() {
super.viewDidLoad()
if NSProcessInfo.processInfo().activeProcessorCount > 1 {
self.filterView.contentMode = .ScaleAspectFill
var emptyFilter = SCFilter.emptyFilter()
emptyFilter.name = "#nofilter"
self.filterView.filters = [emptyFilter, SCFilter(CIFilterName:"CIPhotoEffectNoir"), SCFilter(CIFilterName:"CIVignetteEffect"), SCFilter(CIFilterName:"CIPhotoEffect") ]
self.player.SCImageView = self.filterView
self.filterView.addObserver(self, forKeyPath: "selectedFilter", options: .New, context: nil)
}
else {
var playerView = SCVideoPlayerView(player: player)
playerView.playerLayer!.videoGravity = "ResizeAspectFill"
playerView.frame = self.filterView.frame
playerView.autoresizingMask = self.filterView.autoresizingMask
self.filterView.superview!.insertSubview(playerView, aboveSubview: self.filterView)
self.filterView.removeFromSuperview()
}
player.loopEnabled = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

Related

Passing image from ViewController to ViewController

I try to pass an image from one ViewController1 to another ViewController2 when a button is tapped. I am using segues in my Storyboard.
ViewController1
import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
var imagePicker: UIImagePickerController!
#IBAction func editPhoto(_ sender: UIButton) {
let editViewController = storyboard?.instantiateViewController(withIdentifier: "EditImageViewController") as! EditImageViewController
editViewController.imageForEdit = imageView.image!
print(imageView)
print(imageView.image!)
navigationController?.pushViewController(editViewController, animated: true)
}
#IBOutlet weak var imageView: UIImageView! {
didSet {
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
print(imageView) results in
some(UIImageView: 0x7fc34df0e630; frame = (8 29; 303 443); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = CALayer: 0x60000023e520)
and print(imageView.image!) in
size {3000, 2002} orientation 0 scale 1.000000
ViewController2
import UIKit
class EditImageViewController: UIViewController {
var imageForEdit = UIImage()
#IBOutlet weak var editingImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
editingImage.image = imageForEdit
print(imageForEdit)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
print(imageForEdit) results in
size {0, 0} orientation 0 scale 1.000000
Why is that? Why isnt the image passed to ViewController2?
It seems to me that this could be a lot simpler. If you're using a Storyboard with a segue, you can easily accomplish this in prepare(for segue: UIStoryboardSegue, sender: Any?). Here's a sample storyboard:
In this case, ViewController has a segue on the Edit Image button to the EditImageViewController.
When you push that button, you get your prepare(for segue: call. Here's a sample ViewController:
class ViewController: UIViewController {
var imagePath = Bundle.main.path(forResource: "icon8", ofType: "png")
var anEditableImage:UIImage?
override func viewDidLoad() {
super.viewDidLoad()
if let imagePath = imagePath {
anEditableImage = UIImage(contentsOfFile: imagePath)
}
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? EditImageViewController {
destination.imageForEdit = anEditableImage
}
}
}
And here's the EditImageViewController:
class EditImageViewController: UIViewController {
var imageForEdit:UIImage?
override func viewDidLoad() {
super.viewDidLoad()
print(imageForEdit ?? "Image was nil")
}
}
Using prepare(for segue: UIStoryboardSegue, sender: Any?) is the preferred way for a Storyboard-based app to pass data between View Controllers. It's very simple and it works.
Sample project is here if you want to see the working code:
https://www.dropbox.com/s/eog01bmha67c5mv/PushImage.zip?dl=0
var imageForEdit: UIImage? {
didSet {
editingImage.image = imageForEdit
}
}
Replace var imageForEdit = UIImage() with var imageForEdit : UIImage?
i test code my self , make sure that imageView have image
#IBOutlet weak var imageView: UIImageView! {
didSet {
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
}
}
You can create an public variable so you can pase data from one viewcontroller to another view controller.
class variables
{
static var image = UIImage()
}
the 2 controller:
#IBOutlet weak var anotherviewcontroller: UIImageView!
anotherviewcontroller.image = variables.image

Swift 3: Instance Member cannot be used on type “View Controller”

I'm trying to update a UIimageview image with a method inside a class with a viewDidLoad() call. I'm trying to change the image by:
MyIMage.image = UIImage(named: "image2")
but its giving me the error of:
Instance member cannot be used on type "view controller"
Where am I going wrong?
My Code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var MyImage: UIImageView!
var MyStruct = ChangeImage()
struct ChangeImage {
private var _isChanged: Bool = false
mutating func Set_Change(val: Bool) {
if (val) {
MyImage.image = UIImage(named: "image2")
self._isChanged = true
} else {
MyImage.image = UIImage(named: "image1")
self.isChanged = false
}
}
func isChanged()-> Bool {
return self._isChanged
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
MyStruct.Set_Change(val: true)
print (MyStruct.isChanged())
}
}
Here is the extract of the code corrected but with the same error in line : let _myImage = MyImage()
class ViewController: UIViewController {
#IBOutlet var MyImage: UIImageView!
var MyStruct = ChangeImage()
struct ChangeImage {
private var _isChanged: Bool = false
let _myImage = MyImage() // ----> Error : Instance member ‘MyImage’ cannot be used on type ‘ViewController’
mutating func Set_Change(val: Bool) {
if (val) {
_myImage.image = UIImage(named: "image2")
self._isChanged = true
} else {
_myImage.image = UIImage(named: "image1")
self._isChanged = false
}
}
func isChanged()-> Bool {
return self._isChanged
}
}
I think your problem is that the structure can't use the variable from the ViewController class, so I changed it to a function that does the same thing:
import UIKit
class ViewController: UIViewController {
#IBOutlet var myImage: UIImageView!
func Set_Change(val: Bool) -> Bool {
if (val) {
myImage.image = UIImage(named: "image2")
return true
} else {
myImage.image = UIImage(named: "image1")
return false
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let didChange = Set_Change(val: true)
print(didChange)
}
}
Here's the solution that works :
import UIKit
class ViewController: UIViewController {
#IBOutlet var MyImage: UIImageView! // Insert Outlet Image : "MyImage"
// Structure ChangeImage
struct ChangeImage {
private var _isChanged: Bool = false
private var _myImage: UIImageView! // Private variable _myImage
init (ImgView: UIImageView) { // Initiate ImgView called since func viewDidLoad()
self._myImage = ImgView // Private variable _myImage = ImgView ( variable MyImage in func viewDidLoad() )
}
mutating func Set_Change(val: Bool) {
if (val) {
_myImage.image = UIImage(named: "image2")
self._isChanged = true
} else {
_myImage.image = UIImage(named: "image1")
self._isChanged = false
}
}
func isChanged()-> Bool {
return self._isChanged
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var MyStruct = ChangeImage(ImgView: MyImage) // Initiate Structure ChangeImage with variable MyImage.
MyStruct.Set_Change(val: true)
print (MyStruct.isChanged())
}
}
;)

Custom UIView label and animation not showing up in view controller

I actually have a custom uiview that works, and I think everything in the uiview that doesn't work is set up the same as the one that works. Here is the code:
protocol SessionDisplayViewDelegate: class
{
func homeButtonTapped()
}
class SessionDisplayView: UIView
{
#IBOutlet var view: UIView!
#IBOutlet weak var accountImage: UIButton!
#IBOutlet weak var mySKView: SKView!
#IBOutlet weak var sessionTitle: UILabel!
weak var delegate: SessionDisplayViewDelegate?
required init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)!
commonInitialization()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInitialization()
}
func commonInitialization()
{
Bundle.main.loadNibNamed("SessionDisplayView", owner: self, options: nil)
self.addSubview(self.view)
//accountImage = UIImage(data: ShareData.sharedInstance.accounts[ShareData.sharedInstance.indexOfCurrentAccount].picture!, scale: 1.0)
}
func onView()
{
let curScene = MyScene(size: mySKView.bounds.size)
curScene.scaleMode = SKSceneScaleMode.aspectFill
mySKView.presentScene(curScene)
let myImage = UIImage(data: (ShareData.sharedInstance.accounts[ShareData.sharedInstance.indexOfCurrentAccount]?.picture!)! as Data, scale: 0.5)
accountImage.setImage(myImage, for: UIControlState())
sessionTitle.text = ShareData.sharedInstance.accounts[ShareData.sharedInstance.indexOfCurrentAccount]?.name
var myTest = sessionTitle.text
self.view.setNeedsDisplay()
}
#IBAction func homeButtonTouched(_ sender: UIButton)
{
delegate?.homeButtonTapped()
}
}
I don't know that the self.view.setNeedsDisplay() needs to be called- I'm just trying to make it work. The title doesn't change even though the variable for the title does change- I've checked that, and that is working. Either there's a connection issue between the label and the variable, or the view controller isn't getting the update signal to change the view controller. I don't know which- and I don't know how to nail down which it is, either. Any ideas on how to fix this would be deeply appreciated. Here is the ViewController code:
class SessionDisplayViewController: UIViewController, SessionDisplayViewDelegate
{
#IBOutlet weak var mySessionView: SessionDisplayView!
func homeButtonTapped()
{
self.performSegue(withIdentifier: "ReturnHome", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
mySessionView.onView()
mySessionView.sessionTitle.text = "Test"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var shouldAutorotate : Bool {
if (UIDevice.current.orientation == UIDeviceOrientation.landscapeLeft) || (UIDevice.current.orientation == UIDeviceOrientation.landscapeRight) || (UIDevice.current.orientation == UIDeviceOrientation.unknown)
{
return true
}
else
{
return false
}
}
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
return [UIInterfaceOrientationMask.portrait, UIInterfaceOrientationMask.portraitUpsideDown]
}
override var preferredStatusBarStyle : UIStatusBarStyle
{
return UIStatusBarStyle.lightContent
}
}
Any thoughts or suggestion on how to get the UIView to update would be most welcome. Thanks.
Sincerely,
Sean
How does you add your custom view to your root view? From code or from xib/storyboard? If you done that by xib/storyboard you must override awakeFromNib method in your custom view class and call commonInitialization inside it. init() method was call only if you create your view by code.

Using same button to Play/Pause and loop audio in AVFoundation

I have tried linking the action to the same button but this stops the button from working altogether. I can get it working using the same code if I create a separate button:
#IBAction func Play(sender: AnyObject) {
SoundPlayer.play()
}
#IBAction func stop(sender: AnyObject) {
SoundPlayer.stop()
}
I also need the audio to loop.
Using Nirav code:
class ViewController: UIViewController {
var SoundPlayer:AVAudioPlayer = AVAudioPlayer()
#IBOutlet var btnPlay: UIButton!
#IBOutlet var btnStop: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let FileLocation = NSBundle.mainBundle().pathForResource("Aspirin", ofType: ".mp3")
do {
SoundPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: FileLocation!))
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try AVAudioSession.sharedInstance().setActive(true)
}
catch {
print(error)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btnTap(sender: UIButton) {
if (sender == self.btnPlay) {
}
else if (sender == self.btnStop) {
}
}
}
1 - Screenshot of storyboard
You can do that just create IBOutlet of both button like this
#IBOutlet var btnPlay: UIButton!
Now bind this action to both button
#IBaction func btnTap(sender: UIButton) {
if (!sender.selected) {
SoundPlayer.play()
}
else {
SoundPlayer.stop()
}
sender.selected = !sender.selected
}
Hope this will help you

how to hide button when clicked from another view

I am a beginner of xcode programming. I am trying to do an action, when i click button from A view, the button of B view will be hidden. I already know i can use button.hidden = true; for self view controller but I don't know how to control button from other view.
Thanks
#IBAction func TestBut(sender: UIButton) {
setting.hidden = false
}
Before, you create a custom view with button, button action and a protocol as:
protocol CustomViewDelegate {
func buttonPressed (sender: AnyObject)
}
class CustomView: UIView {
#IBOutlet weak var button: UIButton!
var delegate: CustomViewDelegate!
override func awakeFromNib() {
super.awakeFromNib()
}
class func loadViewFromXib() -> CustomView {
return NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil)[0] as! CustomView
}
#IBAction func buttonPressed(sender: AnyObject) {
self.delegate.buttonPressed(sender)
}
}
In your ViewController.
class ViewController: UIViewController, CustomViewDelegate {
var firstView: CustomView?
var secondView: CustomView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.firstView = CustomView.loadViewFromXib()
self.secondView = CustomView.loadViewFromXib()
firstView!.frame = CGRectMake(0, 0, 100, 100)
secondView!.frame = CGRectMake(0, 200, 100, 100)
firstView!.delegate = self
secondView!.delegate = self
self.view.addSubview(firstView!)
self.view.addSubview(secondView!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func buttonPressed(sender: AnyObject) {
if (sender as! UIButton) == self.firstView!.button {
self.secondView?.button.hidden = true
}else {
self.firstView?.button.hidden = true
}
}
}
the button has to be a property of the view( or view controller).
A call would look like this:
view.button.hidden = true

Resources