Powered By Blogger
Showing posts with label Apple Sample Code. Show all posts
Showing posts with label Apple Sample Code. Show all posts

Friday, May 3, 2019

how to record/capture screen in iOS with the help of Swift programming?

Hello everyone,

- Nowadays, I'm working for screen recording operation in my one of the projects and it's really an interesting one which I want to share with my blog's followers.

- Please check below code lines for detailed information about implementation with Swift.


import Foundation
import ReplayKit
import AVKit

/// A customised class for Video & Audio recording functionality
class ScreenRecorder {
    var assetWriter: AVAssetWriter?
    var videoInput: AVAssetWriterInput?
    var audioInput: AVAssetWriterInput?
    var recorder = RPScreenRecorder.shared()
    var fileURL: URL?
    var timer: Timer?
    
    // MARK: ====================================
    // MARK: ScreenRecorder with Capture Screen event
    // MARK: ====================================
    
    func startRecording(withFilepath fileURL: URL, recordingHandler:@escaping (Error?) -> Void) {
        do {
            assetWriter = try AVAssetWriter(outputURL: fileURL, fileType:
                AVFileType.mp4)
            //-- Video Input
            let videoOutputSettings: [String: Any] = [
                AVVideoCodecKey: AVVideoCodecType.h264,
                AVVideoWidthKey: UIScreen.main.bounds.size.width,
                AVVideoHeightKey: UIScreen.main.bounds.size.height,
                AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey: 2300000,
                                                  AVVideoProfileLevelKey: AVVideoProfileLevelH264High40]
            ]
            //-- Audio Input
            var channelLayout = AudioChannelLayout()
            channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_D
            let audioOutputSettings: [String: Any] = [
                AVNumberOfChannelsKey: 6,
                AVFormatIDKey: kAudioFormatMPEG4AAC_HE,
                AVSampleRateKey: 44100,
                AVEncoderBitRateKey: 128000,
                AVChannelLayoutKey: NSData(bytes: &channelLayout, length: MemoryLayout.size(ofValue: channelLayout))
            ]
            
            audioInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioOutputSettings)
            videoInput = AVAssetWriterInput (mediaType: .video, outputSettings: videoOutputSettings)
            
            audioInput?.expectsMediaDataInRealTime = true
            videoInput?.expectsMediaDataInRealTime = true
            
            assetWriter?.add(audioInput!)
            assetWriter?.add(videoInput!)
            
            recorder.isMicrophoneEnabled = true
            recorder.startCapture(handler: { (sample, bufferType, error) in
                recordingHandler(error)
                if CMSampleBufferDataIsReady(sample) {
                    if self.assetWriter?.status == AVAssetWriter.Status.unknown {
                        self.assetWriter?.startWriting()
                        self.assetWriter?.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(sample))
                    }
                    if self.assetWriter?.status == AVAssetWriter.Status.failed {
                        print("Error occured, status = \(String(describing: self.assetWriter?.status.rawValue)), \(String(describing: self.assetWriter?.error?.localizedDescription)) \(String(describing: self.assetWriter?.error))")
                        self.assetWriter?.cancelWriting()
                        self.assetWriter?.endSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(sample))
                        recordingHandler(error)
                        return
                    }
                    //-- Video Data
                    if (bufferType == .video), let isReadyForMoreMediaData = self.videoInput?.isReadyForMoreMediaData, isReadyForMoreMediaData == true {
                        self.videoInput?.append(sample)
                    }
                    //-- Audio Data
                    if (bufferType == .audioApp || bufferType == .audioMic), let isReadyForMoreMediaData = self.audioInput?.isReadyForMoreMediaData, isReadyForMoreMediaData == true {
                        self.audioInput?.append(sample)
                    }
                }
            }, completionHandler: { (error) in
                recordingHandler(error)
            })
        } catch {
            recordingHandler(error)
        }
    }
    
    func stopRecording(handler: @escaping (Error?) -> Void) {
        recorder.stopCapture { (error) in
            handler(error)
            if self.assetWriter?.status == AVAssetWriter.Status.failed || self.assetWriter?.status == AVAssetWriter.Status.cancelled || self.assetWriter?.status == AVAssetWriter.Status.unknown || self.assetWriter?.status == AVAssetWriter.Status.completed {
                return
            } else {
                self.audioInput?.markAsFinished()
                self.videoInput?.markAsFinished()
                self.assetWriter?.finishWriting(completionHandler: {
                })
            }
        }
    }
    
   class func createReplaysFolder() {
        // path to documents directory
        let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
        if let documentDirectoryPath = documentDirectoryPath {
            // create the custom folder path
            let replayDirectoryPath = documentDirectoryPath.appending("/Replays")
            let fileManager = FileManager.default
            if !fileManager.fileExists(atPath: replayDirectoryPath) {
                do {
                    try fileManager.createDirectory(atPath: replayDirectoryPath,
                                                    withIntermediateDirectories: false,
                                                    attributes: nil)
                } catch {
                    print("Error creating Replays folder in documents dir: \(error)")
                }
            }
        }
    }
    
   class func filePath(_ fileName: String) -> String {
        createReplaysFolder()
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        let documentsDirectory = paths[0] as String
        let filePath: String = "\(documentsDirectory)/Replays/\(fileName).mp4"
        return filePath
    }
}

// MARK: ====================================
// MARK: ScreenRecorder with Recording Event
// MARK: ====================================

extension ScreenRecorder {
    //-- Start screen recording event
    func startRecording(recordingHandler: @escaping(String?) -> Void) {
        guard recorder.isAvailable else {
            recordingHandler("Recording is not available at this time.")
            return
        }
        //recorder.delegate = self
        recorder.isMicrophoneEnabled = true
        recorder.startRecording{ (error) in
            if error == nil {
                #if DEBUG
                print("Started Recording Successfully")
                #endif
                recordingHandler(nil)
            } else {
                recordingHandler(error?.localizedDescription)
            }
        }
    }
    
    //-- Stop screen recording event
    func stopRecording(recordingHandler: @escaping(RPPreviewViewController?, Error?) -> Void) {
        recorder.stopRecording { (preview, error) in
            recordingHandler(preview, error)
        }
    }
}

- Please create one ScreenRecorder.swift file and add the above contents to that file. After this, please import this to another class where you want to implement this functionality. 



For example :


/// Video button click event

@IBAction func btnVideoClicked(_ sender: UIButton) {
    
    sender.isSelected = !sender.isSelected
    
    if sender.isSelected {
        
        startScreenRecording()
        
    } else {
        
        stopScreenRecording()
        
    }
    
}

// MARK: ====================================
// MARK: Start Capturing Part
// MARK: ====================================

/// Start event for Screen Recording
func startScreenRecording() {
    let fileURL = URL(fileURLWithPath: filePath("Recording_\(Date().convertToStringWith(Constants.DateFormates.filedateformat)!)"))
    screenRecorder. startRecording(withFilepath: fileURL!) { (error) in
        if error == nil {
            
        } else {
            #if DEBUG
            print(error ?? "")
            #endif
            sender.isSelected = !sender.isSelected
        }
    }
}

// MARK: ====================================
// MARK: Stop Capturing Part
// MARK: ====================================

/// stop event for Screen Recording
func stopScreenRecording() {
    screenRecorder.stopRecording{ (error) in
        if error == nil {
            sender.isSelected = !sender.isSelected
            // An alert will be displayed to save or delete recorded video
            displayAlertToSaveOrDeleteVideo()
        } else {
            #if DEBUG
            print(error ?? "")
            #endif
        }
    }
}

/// A function to display an alert to save or delete the recorded video
func displayAlertToSaveOrDeleteVideo() {
    DispatchQueue.main.async(execute: {
        let alert = UIAlertController(title: "Recording Finished", message: "Do you want to save or delete recording?", preferredStyle: .alert)
        let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action: UIAlertAction) in
            DispatchQueue.main.async(execute: {
                //-- Share annoted image's local path to upload it on server.
                if let savedAnnotedFilePath = screenRecorder.assetWriter?.outputURL.path, FileManager.shared.fileExists(atPath: savedAnnotedFilePath) {
                    do {
                        try AppInfo.shared.fileManager.removeItem(atPath: savedAnnotedFilePath)

                    // recording deleted successfully

                        
                    } catch {
                        self.view?.makeToast(error.localizedDescription)
                    }
                } else {
                    // recorded_file_not_found
                }
            })
        })
        let editAction = UIAlertAction(title: "Save", style: .default, handler: { (action: UIAlertAction) -> Void in
            DispatchQueue.main.async(execute: {
                //-- Share annoted image's local path to upload it on server.
                if let savedAnnotedFilePath = self.assetWriter?.outputURL.path, AppInfo.shared.fileManager.fileExists(atPath: savedAnnotedFilePath) {
                    // MOVE OR UPLOAD FILE TO DESNTINATION
                } else {
                    // recorded_file_not_found
                }
            })
        })
        alert.addAction(editAction)
        alert.addAction(deleteAction)
        self.present(alert, animated: true, completion: nil)
    })
}


- Try this in your project, you will definitely get success and in case of any issue, post your comment. I will try to respond to it with an appropriate solution.


Regards,

Friday, July 13, 2012

how to compress string according to frame in iphone sdk?

Hi everyone,
Please check the below tip for Compression of string according to your view/controller frame size.
 
        UILabel *lable =[[UILabel alloc]initWithFrame:CGRectMake(X_POS, Y_POS, width, height)];
        lable.tag = tag;
        lable.backgroundColor = [UIColor clearColor];
        lable.lineBreakMode = UILineBreakModeWordWrap;
        lable.numberOfLines = 10.0;


            CGFloat fontHeight = 15.0;
            BOOL huge = YES;
            while (huge)
            {
                CGSize boundingSize = CGSizeMake(lable.frame.size.width, CGFLOAT_MAX);
                CGSize requiredSize = [lable.text sizeWithFont:lable.font
                                             constrainedToSize:boundingSize
                                                 lineBreakMode:UILineBreakModeWordWrap];
                NSLog(@"Width:%f",requiredSize.width) ;
                NSLog(@"Height:%f",requiredSize.height) ;
                NSLog(@"NumberofLines : %f",requiredSize.height/lable.font.lineHeight);
               
                if (lable.frame.size.height<requiredSize.height)
                {
                    fontHeight --;
                    lable.font = [UIFont fontWithName:@"Verdana" size:fontHeight];
                    lable.adjustsFontSizeToFitWidth = YES;
                }
                else
                {
                    huge = NO;
                }
            }

Thanks & Regards,
Nilesh Prajapati

Wednesday, June 13, 2012

iPhone/iOS/iPad/Apple Sample Code

 Hi everyone,
Sample code is one of the most useful tools for learning about programming. Here's a collection of links I've found so far. Does anyone know of some other sources for iPhone sample code?

    •    Apple Sample Code: http://developer.apple.com/iphone/library/navigation/SampleCode.html
    •    Apps Amuck 31 days: http://appsamuck.com/
    •    Beginning iPhone Development: http://www.iphonedevbook.com/
    •    Chris Software: http://chris-software.com/index.php/dev-center/
    •    Dave DeLong's downloads: http://www.davedelong.com/downloads
    •    Delicious.com: http://delicious.com/alblue/iphonehttp://web.me.com/smaurice/AppleCoder/iPhone%5FOpenGL/Archive.htmlhttp://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html
    •    iPhone Developer's Cookbook: http://code.google.com/p/cookbooksamples/downloads/list
    •    iPhone SDK source code: http://sites.google.com/site/iphonesdktutorials/sourcecode
    •    Joe Hewitt three20: http://joehewitt.com/post/the-three20-project/
    •    Stanford iPhone code: http://www.stanford.edu/class/cs193p/cgi-bin/downloads.php
    •    WiredBob (TabBar in Detail view): http://www.wiredbob.com/blog/2009/4/20/iphone-tweetie-style-navigation-framework.html
    •    BYU Cocoaheads : http://cocoaheads.byu.edu/
    •    Big Nerd Ranch: http://weblog.bignerdranch.com/
    •    Cocoa with love: http://cocoawithlove.com/
    •    Will Shipley: http://wilshipley.com/blog/
    •    mobile.tuts: http://mobile.tutsplus.com/
  
                                            •    Just sample code:
  
    •    Google Code: http://code.google.com/hosting/search?q=label%3Aiphone
    •    iPhone Cool Projects: http://www.apress.com/book/view/143022357x
    •    iPhone Game Projects: http://www.apress.com/book/downloadfile/4419
    •    Learn Objective-C on the Mac: http://www.apress.com/book/downloadfile/4175
    •    iCode Blog: http://icodeblog.com/
    •    Raywenderlich Tutorials: http://www.raywenderlich.com/
    •    OpenGLS: http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html