Play MP4 using MPMoviePlayerController() in Swift - swift

I can't for the life of me figure out a way to play an MP4 that takes up the entire background in a UIViewController.
So far I have the following, which doesn't even play the video at all.
I can confirm that the bokeh.mp4 video exists because if I change the file to something else then it throws an error that it's missing.
override func viewDidAppear(animated: Bool) {
let filePath = NSBundle.mainBundle().pathForResource("bokeh", ofType: "mp4")
self.moviePlayerController.contentURL = NSURL(string: filePath)
self.moviePlayerController.prepareToPlay()
self.moviePlayerController.repeatMode = .One
self.moviePlayerController.controlStyle = .Embedded
self.view.addSubview(self.moviePlayerController.view)
}
I get an error in the console:
2014-06-22 21:22:42.347 MoviePlayer[26655:60b] _itemFailedToPlayToEnd: {
kind = 1;
new = 2;
old = 0;
}
I've also tried adding a UIView that takes up the entire screen and adding the player to that view, but it's the same problem. It doesn't start playing.
I'm trying to achieve the same effect that Vine has when you first load up the application where it has the video playing in the background.

So this was blindly annoying:
All I did was change:
self.moviePlayerController.contentURL = NSURL(string: filePath)
TO:
self.moviePlayerController.contentURL = NSURL.fileURLWithPath(filePath)

Related

Failed to get video thumbnail from AVPlayer using Fairplay HLS

I'm trying to build a custom progress bar for a video player app in tvOS, and would like to show thumbnails of the video while the user scans the video.
I'm using AVPlayer and Fairplay HLS to play remote video files. I've tried to do this using 2 methods. One with AVAssetImageGenerator's copyCGImage, and the other with AVPlayerItemVideoOutput's copyPixelBuffer method. Both return nil.
When I tried with a local video file, the first method worked.
Method 1:
let imageGenerator = AVAssetImageGenerator(asset: playerItem.asset)
let progressSeconds = playerItem.duration.seconds * Double(progress)
let time = CMTime(seconds: progressSeconds, preferredTimescale: 5)
if let imageRef = try? imageGenerator.copyCGImage(at: time, actualTime: nil) {
image = UIImage(cgImage:imageRef)
}
Method 2:
let videoThumbnailsOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: [String(kCVPixelBufferPixelFormatTypeKey): NSNumber(value: kCVPixelFormatType_32BGRA)])
player?.currentItem?.add(videoThumbnailsOutput)
if let pixelBuffer = videoThumbnailsOutput.copyPixelBuffer(forItemTime: time, itemTimeForDisplay: nil) {
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
Any ideas what I'm doing wrong or is there any other way?
Thanks!
This is usually done by making use of the trick play stream associated to your actual stream.
https://en.wikipedia.org/wiki/Trick_mode
You can find it declared with the key EXT-X-I-FRAME-STREAM-INF in the manifest of your HLS stream. A regex might be needed in order to parse its value.
"#EXT-X-I-FRAME-STREAM-INF[^#]*URI=[^#]*"
Once you have the URL of the trick play stream, you can use a paused instance of AVPlayer as a thumbnail. And when the user swipe left and right, you should seek the player in the thumbnail to show the right frame.

AudioPlayer (Swift) - play sound twice - with gap

I'm using the following code to play a sound file twice. The second sound plays immediately following the first
Is it possible to leave a time gap (1 second) between them? I've tried to find a solution reading the Apple Docs
var letterSound: AVAudioPlayer!
...
#IBAction func speakLetter(sender: AnyObject) {
let soundFile: String = "SoundFile" + String(letterNumber)
let path = Bundle.main.path(forResource: soundFile, ofType:"mp3")!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
letterSound = sound
letterSound.numberOfLoops = 1
letterSound.play()
} catch {
// couldn't load file :(
}
}
One option would be to add some 'white space' or silence at the end of your audio file.
If you don't have an audio editor i'd recommend Audacity, it's free and there are lots of tutorials on how to add silence.
If you want a more code based option you could look in to using the AVAudioPlayerDelegate didFinishPlaying method to detect the end of the first play and then use play(atTime:) to trigger the next loop 1 second from now.
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
player.play(atTime: player.deviceCurrentTime + 1.0)
}
This code is untested and I think it might create an infinite loop so you may need some additional logic here to make sure it only loops once

How to send audio file with image and caption in iMessage app for iOS 10?

I am creating iMessage app and trying to send audio or video file to other user.
Video file works and looks fine but its not working as expected with audio file.
My current code is:
let destinationFilename = mp3FileNames[i]
let destinationURL = docDirectoryURL.appendingPathComponent(destinationFilename)
if let conversation = activeConversation {
let layout = MSMessageTemplateLayout()
layout.image = UIImage.init(named: "audio-x-generic-icon")
layout.mediaFileURL = destinationURL
layout.caption = selectedSongObj.name
let message = MSMessage()
message.layout = layout
message.url = URL(string: "emptyURL")
conversation.insert(message, completionHandler: nil)
return
}
Looks like layout.mediaFileURL = destinationURL is not adding any file into message.
And when I try to send file with above code.It looks like shown below:
It looks fine but there is no audio to play but if I try this way:
let destinationFilename = mp3FileNames[i]
let destinationURL = docDirectoryURL.appendingPathComponent(destinationFilename)
if let conversation = activeConversation {
conversation.insertAttachment(destinationURL!, withAlternateFilename: nil, completionHandler: nil)
return
}
And result with above code is:
I can play audio for that message because it's there. But problem with that message is I can not attach any image or caption with it.
How can I attach image and audio file into same message.
And if possible instead of image can I add GIF?
Any help would be much appreciated, Thank you.
Not necessary to use GIF, iMessage extensions supports also PNGand JPEG image formats. Recommended image size is 300x300 points at #3x scale.
If the MSMessageTemplateLayout's image property has a non-nil value then
mediaFileURL property is ignored. So you can't send an image and an audio file at the same time. Docs

Getting sounds to work right

I am trying to add sound effects to a game app I am making in Xcode 6. Here is the code that I am using to play the sounds:
var jumpSoundPlayer:AVAudioPlayer = AVAudioPlayer()
var jumpAudioPath:String = ""
var jumpSoundError: NSError? = nil
func setUpSoundPlayers(){
jumpAudioPath = NSBundle.mainBundle().pathForResource("Jump", ofType: "mp3")!
jumpSoundError = nil
jumpSoundPlayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: jumpAudioPath), fileTypeHint: "mp3", error: &jumpSoundError)
}
func playJumpSound(volume:Float = 1){
jumpSoundPlayer.volume = volume
jumpSoundPlayer.play()
}
I can get sounds to play, but it seems as though it will not play a sound until the one currently playing is finished. How can I get it so that multiple sounds can play at once and overlap each other?
Also, every time a sound plays it drops the frame rate down a little bit. Is there a way to fix that?
I believe you have to use
jumpSoundPlayer.prepareToPlay()
before using
jumpSoundPlayer.play()
Also the only solution to drop the frame rate a little less, is to set up all the AVAudioPlayers before using them or at the beginning of the game.

How can I play an intro video the first time I launch an iPhone app using swift (NOT objective-c)?

I want to play an intro video for my iPhone app the first time it launches. I have it set up to detect that it's the first launch, but how do I play the video from the app (not a url) using SWIFT? Do I set it up in the first ViewController file or in the AppDelegate? I've tried using MPMoviePlayerController, but I just can't seem to get it to actually play. Thank you for your help!
I had this same trouble. Here's my solution:
func playVideo() {
let path = NSBundle.mainBundle().pathForResource("video", ofType:"mp4")
let url = NSURL.fileURLWithPath(path!)
moviePlayer = MPMoviePlayerController(contentURL: url)
if let player = moviePlayer {
player.view.frame = self.view.bounds
player.controlStyle = .None
player.prepareToPlay()
player.scalingMode = .AspectFit
self.view.addSubview(player.view)
}
}
Don't forget to import MediaPlayer and declare your variable - var moviePlayer: MPMoviePlayerController?
Then call your function when you want to play it playVideo()
See my question for how to dismiss it - In iOS how do I programmatically add a video view and then remove it after it finishes playing using Swift?
I got a really helpful answer there.
Also notice that I disabled my controllers because I don't want it to be seen.