multimedia - washington state universityholder/courses/mad/slides/14-multimedia.pdf · multimedia...

38
Multimedia Mobile Application Development in iOS School of EECS Washington State University Instructor: Larry Holder Mobile Application Development in iOS 1

Upload: others

Post on 23-Jun-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

MultimediaMobile Application Development in iOS

School of EECS

Washington State University

Instructor: Larry Holder

Mobile Application Development in iOS 1

Page 2: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Outline

• Audio recording, access, and playback

– Speech recognition and synthesis

• Image capture, access, and display

• Video recording, access, and playback

Mobile Application Development in iOS 2

Page 3: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Recording and Playback• Use AVFoundation framework

• Configure AVAudioSession singleton class

– Need permission to access microphone

• AVAudioSession.recordPermission == .granted

• AVAudioSession.requestRecordPermission((Bool -> Void))

Mobile Application Development in iOS 3

import AVFoundationclass ViewController: UIViewController {

override func viewDidLoad() {let session = AVAudioSession.sharedInstance()if session.recordPermission != .granted {

session.requestRecordPermission({Bool in})}

}}

Page 4: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Recording and Playback

• Configure AVAudioSession

– setCategory(category, mode, options)

– Category (e.g., AVAudioSession.Category.playAndRecord)

– Mode (e.g., AVAudioSession.Mode.spokenAudio)

– Options (e.g., mixWithOthers, duckOthers, defaultToSpeaker)

• setActive(Bool)

– Request access to audio hardware

– May fail if higher-priority task using audio

Mobile Application Development in iOS 4

Page 5: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Recording and Playback

• Configure and activate audio session

Mobile Application Development in iOS 5

let session = AVAudioSession.sharedInstance()do {

try session.setCategory(AVAudioSession.Category.playAndRecord,mode: AVAudioSession.Mode.spokenAudio, options:

[AVAudioSession.CategoryOptions.duckOthers,AVAudioSession.CategoryOptions.defaultToSpeaker])

try session.setActive(true)} catch {

print("error starting audio session")}

Page 6: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Recording

• Initialize

– AVAudioRecorder(url, settings) throws• Get URL to sound file in documents directory

• Settings dictionary: Need at least AVFormatIDKey– https://developer.apple.com/documentation/coreaudio/core_audio_data_types/157209

6-audio_data_format_identifiers

• Main methods

– prepareToRecord(), record(), pause(), stop()

• AVAudioRecorderDelegate methods

– audioRecorderDidFinishRecording

Mobile Application Development in iOS 6

Note: iOS simulator can access Mac's microphone.

Page 7: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Recording: Setup

Mobile Application Development in iOS 7

class ViewController: UIViewController, AVAudioRecorderDelegate {let audioFile = "audioFile.m4a"var audioFileURL: URL!var audioRecorder: AVAudioRecorder?

override func viewDidLoad() {// Get URL to audio filelet paths = FileManager.default.urls(for: .documentDirectory,

in: .userDomainMask)let docDir = paths[0]audioFileURL = docDir.appendingPathComponent(audioFile)

// Setup audio recorderlet settings = [AVFormatIDKey: kAudioFormatMPEG4AAC]do {

audioRecorder = try AVAudioRecorder(url: audioFileURL,settings: settings)

audioRecorder?.delegate = self} catch {

print("error creating audio recorder")}

}}

Page 8: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Recording

• AVAudioRecorderDelegate method

Mobile Application Development in iOS 8

func startRecording() {audioRecorder?.record()

}

func stopRecording() {audioRecorder?.stop()

}

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder,successfully flag: Bool) {

if flag {print("recording successful")

} else {print("recording failed")

}// Modify view: Change "Stop" to "Start"

}

Page 9: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Playback

• Initialize

– AVAudioPlayer(url) throws• Get URL to sound file in documents directory

• Must be reinitialized when sound file rewritten

• Main methods

– prepareToPlay(), play(), pause(), stop()

– currentTime – set to 0 to return to front

• AVAudioPlayerDelegate methods

– audioPlayerDidFinishPlaying

Mobile Application Development in iOS 9

Page 10: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Playback: Setup

Mobile Application Development in iOS 10

class ViewController: UIViewController, AVAudioPlayerDelegate {var audioFileURL: URL!var audioPlayer: AVAudioPlayer?

func startPlaying() {// Setup audio playerdo {

audioPlayer = try AVAudioPlayer(contentsOf: audioFileURL)audioPlayer?.delegate = self

} catch {print("error accessing audio player")

}audioPlayer?.play()

}

func stopPlaying() {audioPlayer?.stop()

}

}

Page 11: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Audio Playback

• AVAudioPlayerDelegate method

Mobile Application Development in iOS 11

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer,successfully flag: Bool) {

if flag {print("playback finished")

} else {print("playback error")

}// Modify view: Change "Stop" to "Start"

}

Page 12: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Accessing Audio Library• Maintain privacy and DRM

• MediaPlayer framework

– MPMediaPickerController to select audio

– MPMediaPickerDelegate

• mediaPicker(didPickMediaItems)

• mediaPickerDidCancel

– MPMediaPlayerController.applicationQueuePlayer

• setQueue(mediaItemCollection)

• play(), pause(), stop()

Mobile Application Development in iOS 12

Note: No music library in iOS simulator. Need a real device.

Page 13: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Accessing Audio Library

Mobile Application Development in iOS 13

import MediaPlayer

class ViewController: UIViewController, MPMediaPickerControllerDelegate {var mediaPlayer = MPMusicPlayerController.applicationQueuePlayer

@IBAction func selectSongToPlayTapped(_ sender: UIButton) {let mediaPicker = MPMediaPickerController(mediaTypes: .anyAudio)mediaPicker.delegate = selfpresent(mediaPicker, animated: true, completion: {})

}

func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {

mediaPlayer.setQueue(with: mediaItemCollection)mediaPicker.dismiss(animated: true, completion: {})

}

func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) {mediaPicker.dismiss(animated: true, completion: {})

}}

Page 14: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Speech Recognition

• Speech framework

• SFSpeechRecognizer

– requestAuthorization()

• SFSpeechRecognizerDelegate

– speechRecognizer(availabilityDidChange)

Mobile Application Development in iOS 14

Page 15: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Speech Recognition: Setup

Mobile Application Development in iOS 15

import Speechclass ViewController: UIViewController, SFSpeechRecognizerDelegate {

var speechRecognitionAllowed = falsevar speechRecognizer: SFSpeechRecognizer?

override func viewDidLoad() {super.viewDidLoad()SFSpeechRecognizer.requestAuthorization(handleAuth)

}

func handleAuth (status: SFSpeechRecognizerAuthorizationStatus) {switch status {case .authorized:

speechRecognitionAllowed = truespeechRecognizer = SFSpeechRecognizer()speechRecognizer?.delegate = self

default:speechRecognitionAllowed = false

}}

Page 16: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Speech Recognition: Delegate

Mobile Application Development in iOS 16

// Delegate methodfunc speechRecognizer(_ speechRecognizer: SFSpeechRecognizer,

availabilityDidChange available: Bool) {if available {

speechRecognitionAllowed = true} else {

speechRecognitionAllowed = false}

}

Page 17: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Speech Recognition

Mobile Application Development in iOS 17

var spokenText: String = "Hello, world."

func recognizeSpeech () {if speechRecognitionAllowed {

let request = SFSpeechURLRecognitionRequest(url: audioFileURL)request.shouldReportPartialResults = falsespeechRecognizer?.recognitionTask(with: request,

resultHandler: speechRecognitionHandler)}

}

func speechRecognitionHandler (result: SFSpeechRecognitionResult?,error: Error?) {

if let res = result {self.spokenText = res.bestTranscription.formattedStringprint("spoke: \(self.spokenText)")

} else {print("speech recognition error")

}}

Page 18: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Speech Synthesis

Mobile Application Development in iOS 18

import AVFoundation

func synthesizeSpeech() {let speechSynthesizer = AVSpeechSynthesizer()let utterance = AVSpeechUtterance(string: self.spokenText)// utterance.voice = AVSpeechSynthesisVoice(identifier: "...")speechSynthesizer.speak(utterance)

}

Page 19: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Images and Video• Add privacy properties for access to camera and photo library

– Request authorization

• UIImagePickerController

– Take a picture or video

– Select a picture or video from library

• AVFoundation framework

– Lower-level control of image and video assets

Mobile Application Development in iOS 19

Note: iOS simulator cannot access Mac camera. Need real device for testing.

Can drag-and-drop images and videos into Photos app on iOS simulator.

Page 20: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

UIImagePickerController: Properties

• allowsEditing

• sourceType: .photoLibrary, .savedPhotosAlbum, .camera

• mediaTypes

– kUTTypeImage as String, kUTTypeMovie as String

• import MobileCoreServices

– UIImagePickerController.availableMediaTypes(for)

Mobile Application Development in iOS 20

Page 21: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

UIImagePickerController: Delegates

• UIImagePickerControllerDelegate

– imagePickerController(didFinishPickingMediaWithInfo info)• info[UIImagePickerController.originalImage]

• info[UIImagePickerController.editedImage]

– imagePickerControllerDidCancel

• UINavigationControllerDelegate

– Required, but used implicitly

Mobile Application Development in iOS 21

Page 22: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Select Image from Photo Library

Mobile Application Development in iOS 22

import UIKitimport MobileCoreServices // to get kUTTypeImage

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var selectedImage: UIImage?

func selectImageFromLibrary () {if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {

let picker = UIImagePickerController()picker.delegate = selfpicker.allowsEditing = falsepicker.sourceType = .photoLibrarypicker.mediaTypes = [kUTTypeImage as String]self.present(picker, animated: true, completion: nil)

} else {print("photo library not available")

}}

}

Page 23: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Select Image from Photo Library

Mobile Application Development in iOS 23

// UIImagePickerControllerDelegate methods

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {selectedImage = info[.originalImage] as? UIImageimageView.image = selectedImagepicker.dismiss(animated: true, completion: nil)

}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {picker.dismiss(animated: true, completion: nil)

}

Page 24: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Take Picture

Mobile Application Development in iOS 24

func takePicture () { // same as selectImage, except use sourceType .cameraif UIImagePickerController.isSourceTypeAvailable(.camera) {

let picker = UIImagePickerController()picker.delegate = selfpicker.allowsEditing = falsepicker.sourceType = .camerapicker.mediaTypes = [kUTTypeImage as String]self.present(picker, animated: true, completion: nil)

} else {print("camera not available")

}}

Page 25: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Save Image to File

Mobile Application Development in iOS 25

func writeImage(_ image: UIImage, to fileName: String) {if let directoryURL = FileManager.default.urls(for: .documentDirectory,

in: .userDomainMask).first {let fileURL = directoryURL.appendingPathComponent(fileName)// Can also use image.pngData, but rotates imageif let imageData = image.jpegData(compressionQuality: 1.0) {

do {try imageData.write(to: fileURL)

} catch {print("\(error)")

}} else {

print("Unable to convert image to jpeg.")}

} else {print("Error accessing document directory.")

}}

Page 26: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Read Image from File

Mobile Application Development in iOS 26

func readImage(from fileName: String) -> UIImage? {if let directoryURL = FileManager.default.urls(for: .documentDirectory,

in: .userDomainMask).first {let fileURL = directoryURL.appendingPathComponent(fileName)do {

let imageData = try Data(contentsOf: fileURL)let image = UIImage(data: imageData)return image

} catch {print("\(error)")

}} else {

print("Error accessing document directory.")}return nil

}

Page 27: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Save Image to Photo Library

• UIImageWriteToSavedPhotosAlbum(image: UIImage,

completionTarget: Any?, // self

completionSelector: Selector?, // #selector(imageWriteHandler)

contextInfo: UnsafeRawPointer?) // nil

• func imageWriteHandler(image: UIImage,

didFinishSavingWithError error: Error?,

contextInfo: UnsafeRawPointer?)

Mobile Application Development in iOS 27

Page 28: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Save Image to Photo Library

Mobile Application Development in iOS 28

func saveImage () {if let image = selectedImage {

UIImageWriteToSavedPhotosAlbum(image, self,#selector(imageWriteHandler), nil)

}}

@objc func imageWriteHandler(_ image: UIImage,didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer?) {

if let err = error {print("error saving image: \(err.localizedDescription)")

} else {print("image saved to camera roll")

}}

Page 29: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Working with Video

• Selecting video from library similar to images

– Still use UIImagePickerController

– Use mediaType kUTTypeMovie

• Delegate method gets URL to video

• Play video using AVPlayer and AVPlayerViewController

• Recording video similar to images

– Authorize use of microphone

• Saving video similar to images

Mobile Application Development in iOS 29

Page 30: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Select Video from Library

Mobile Application Development in iOS 30

import UIKitimport MobileCoreServices // to get kUTTypeMovie

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

var videoURL: URL?

func selectVideo () {if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {

let picker = UIImagePickerController()picker.delegate = selfpicker.allowsEditing = falsepicker.sourceType = .photoLibrarypicker.mediaTypes = [kUTTypeMovie as String]self.present(picker, animated: true, completion: nil)

} else {print("video library not available")

}}

Page 31: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Select Video from Library

Mobile Application Development in iOS 31

// UIImagePickerControllerDelegate methods

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {videoURL = info[.mediaURL] as? URLpicker.dismiss(animated: true, completion: nil)

}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {picker.dismiss(animated: true, completion: nil)

}

Page 32: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Play Video

Mobile Application Development in iOS 32

import AVKit // for AVPlayerViewControllerimport AVFoundation // for AVPlayer

func playVideoInNewView () {if let url = videoURL {

let playerView = AVPlayerViewController()playerView.player = AVPlayer(url: url)present(playerView, animated: true, completion: nil)

}}

@IBOutlet weak var videoView: UIView!

func playVideoInSubView () {if let url = videoURL {

let playerView = AVPlayerViewController()playerView.player = AVPlayer(url: url)playerView.view.frame = videoView.frameself.addChild(playerView) // initialize player viewself.view.addSubview(playerView.view) // display player view

}}

Page 33: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Record Video

Mobile Application Development in iOS 33

func recordVideo () { // same as selectVideo, except use sourceType .cameraif UIImagePickerController.isSourceTypeAvailable(.camera) {

let picker = UIImagePickerController()picker.delegate = selfpicker.allowsEditing = falsepicker.sourceType = .camerapicker.mediaTypes = [kUTTypeMovie as String]self.present(picker, animated: true, completion: nil)

} else {print("camera not available")

}}

Page 34: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Save Video to File

Mobile Application Development in iOS 34

let videoFileName = "myVideo.mov" // .mov extension important

func writeVideo(_ videoURL: URL?, to fileName: String) {if let directoryURL = FileManager.default.urls(for: .documentDirectory,

in: .userDomainMask).first {let fileURL = directoryURL.appendingPathComponent(fileName)if let vidURL = videoURL {

do {let videoData = try Data(contentsOf: vidURL)try videoData.write(to: fileURL)

} catch {print("\(error)")

}}

} else {print("Error accessing document directory.")

}}

Page 35: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Read Video from File

Mobile Application Development in iOS 35

// Just return URL to video filefunc getVideoFileURL(from fileName: String) -> URL? {

if let directoryURL = FileManager.default.urls(for: .documentDirectory,in: .userDomainMask).first {

let fileURL = directoryURL.appendingPathComponent(fileName)return fileURL

} else {print("Error accessing document directory.")

}return nil

}

Page 36: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Save Video to Library

• UISaveVideoAtPathToSavedPhotosAlbum(videoPath: String,

completionTarget: Any?, // self

completionSelector: Selector?, // #selector(videoWriteHandler)

contextInfo: UnsafeRawPointer?) // nil

• func videoWriteHandler(videoPath: String,

didFinishSavingWithError error: Error?,

contextInfo: UnsafeRawPointer?)

Mobile Application Development in iOS 36

Page 37: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Save Video to Library

Mobile Application Development in iOS 37

func saveVideoToLibrary () {if let videoPath = videoURL?.path {

UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, #selector(videoWriteHandler), nil)

}}

@objc func videoWriteHandler(_ videoPath: String,didFinishSavingWithError error: Error?,

contextInfo: UnsafeRawPointer?) {if let err = error {

print("error saving video: \(err.localizedDescription)")} else {

print("video saved to library")}

}

Page 38: Multimedia - Washington State Universityholder/courses/MAD/slides/14-Multimedia.pdf · Multimedia Mobile Application Development in iOS School of EECS Washington State University

Resources• AVFoundation and AVKit (more media tools here)

– developer.apple.com/avfoundation/

– developer.apple.com/documentation/avkit

• MediaPlayer framework

– developer.apple.com/documentation/mediaplayer

• Speech framework

– developer.apple.com/documentation/speech

• UIImagePickerController

– developer.apple.com/documentation/uikit/uiimagepickercontroller

Mobile Application Development in iOS 38