How do I play a video file which is not included in my app bundle?
I am able to play videos within my app bundle
#IBOutlet weak var playerView: AVPlayerView!
override func viewDidLoad() {
super.viewDidLoad()
let videoUrl = Bundle.main.url(forResource: "captionsSample", withExtension: "mp4")!
let item = AVPlayerItem(url: videoUrl)
let player = AVPlayer(playerItem: item)
playerView.player = player
}
But when I try to play from desktop or some other location, AVPlayer wont play it.
I would like to build a video player which plays a video file as soon as it gets clicked.
I also checked the Apple tutorial, but it only demonstrates how to play videos at the remote location.
As #vadian suggested, the issue was that my application was sandboxed. If you turn off sandboxing you will be able to read/write any file outside of app bundle. This may seam like a convenient solution, but is not recommended. The recommended way would be to leave the sanboxing turned on and add the needed permissions to your entitlements file.
Related
I am new to Sprite Kit and currently developing my first Game.
Now I want to add some background music (and maybe later some effects) to it and tried it with this piece of code:
func playBackgroundMusic() {
// 1 - Create player
let url = Bundle.main.url(forResource: "mySong", withExtension: "mp3")!
let player = try! AVAudioPlayer(contentsOf: url)
// 2 - Play sound
player.play()
}
But for some reason it doesn't work. I noticed that when I play music and then run the game, the music stops but I can't hear my game music.
The player variable is local to the playBackgroundPlayer function. When you start playing the music, the function exits. When the function exits, player no longer exists. That would explain why the music stops.
The fix is to add a property for the AVAudioPlayer to the class or struct that contains the playBackgroundPlayer function. Create the AVAudioPlayer instance when you init the class or struct. Call the play function inside playBackgroundPlayer.
I'm trying to play a local video file and keep getting the following log:
[framework] CUICatalog: Invalid asset name supplied: '(null)'
My video file is in the project directory and also in the main bundle resources. I've tried multiple versions of the syntax to play the video. Here's the code I have for now in a test project:
#IBAction func buttonAction(_ sender: Any) {
if let path = Bundle.main.path(forResource: "slipMovement", ofType:
"mp4") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
present(videoPlayer, animated: true, completion: {
video.play()
})
}
}
When I use a AVplayer and PlayerLayer, I don't get the 'null' messages. It only happens when I use AVPlayerViewController.
I'm fairly new to programming, any help would be very much appreciated as I just can't find a working solution online.
I experienced this same problem when playing downloaded files from AWS S3.
I don't have an explanation for the meaning behind the error message.
But in my case it was because the file was not actually playable.
1. Make sure the path is correct.
I did not use Bundle.
I put the file under the Documents directory and I used FileManager to set the path:
let documentsUrl: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let localFileName: String = "recording.mp4"
let localFileUrl = documentsUrl.appendingPathComponent(localFileName)
print("Playing \(localFileUrl.absoluteString)")
That would print something like this:
file:///var/mobile/Containers/Data/Application/D8AF92BD-D736-4B86-9FF4-C60ABA6C741B/Documents/recording.mp4
2. Make sure the file is actually playable.
For this, I wanted to check what the file is actually like when it's stored on the device.
It turned out that file was "corrupted" (ex. copy/download interrupted), so it really wasn't playable.
Connect the iOS device to your Mac.
From Xcode, go to Window > Devices and Simulators
Look for your device from the Connected list on the left.
Look for your app from the Installed Apps list.
Click the gears on the bottom of the list.
Select Download Container..
Download the *.xcappdata to a local directory
Open the directory in Finder
Right-click on the *.xcappdata, then select Show Package Contents
It should show something like the image below
Check the file's properties and try to play it
3. Make sure the file format is actually supported by AVPlayer
To see the supported AVPlayer formats, use print(AVURLAsset.audiovisualTypes()).
Reference:
https://developer.apple.com/documentation/avfoundation/avurlasset/1386800-audiovisualtypes
Once the path, the file, and the format were all OK, and I was able to play it normally using AVPlayer and AVPlayerViewController.
let player = AVPlayer(url: localFileUrl)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
I have this app in which the main purpose is to record video using AVFoundation, and then saving the outputfile delegate.
On first any normal run the app could properly record and save the video, and I could load the resulting outputfile URL into Avplayer I have on the next viewcontroller.
The AVPlayer would play just fine normally if the Xcode is not re-run. What I mean with rerunning is tapping into the Command+R again or clicking on the Play button on xcode to rebuild re-run.
What happens when I run the app again is that I could still see the files and list them via print, but when I'm trying to access the recorded file the app would no longer play the video. It would seem that the video wasn't loaded properly or anything even if it had already been working earlier. After this happens I could still go on record new ones and play the newly recorded ones, but not the old files.
The old files before rebuild of app would just look like this on AVPlayer
Also the AVPlayer would successfully return .readyToPlay status on my observer.
I'm confused how should I go on fixing this one.
if let videoPreviewController = storyBoard.instantiateViewController(withIdentifier: "VideoPreviewController") as? VideoPreviewController {
let url = NSURL(fileURLWithPath: "file:///var/mobile/Containers/Data/Application/61E182ED-D490-4C7D-BAB7-C90D095C7E43/Documents/Thursday,%208%20June%202017%20at%201:47:51%20PM%20Philippine%20Standard%20Time.mov")
videoPreviewController.player = AVPlayer()
let playerItem = AVPlayerItem.init(url: url as URL)
videoPreviewController.player?.replaceCurrentItem(with: playerItem)
videoPreviewController.report = relationship
videoPreviewController.appointment = self.appointment
navigation.pushViewController(videoPreviewController, animated: true)
}
Your problem is this line:
let url = NSURL(fileURLWithPath: "file:///var/mobile/Containers/Data/Application/61E182ED-D490-4C7D-BAB7-C90D095C7E43/Documents/Thursday,%208%20June%202017%20at%201:47:51%20PM%20Philippine%20Standard%20Time.mov")
That path will change every time your restart your app -- you can't hard code it. You have to ask the OS for the path to your documents folder and append your filename to it.
let userDocumentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileName = "Thursday,%208%20June%202017%20at%201:47:51%20PM%20Philippine%20Standard%20Time.mov"
let movieURL = userDocumentsURL.appendingPathComponent(fileName)
And by the way, that's probably how you saved the file in the first place... get the path, append your filename and save it.
This question already has answers here:
How to embed a Youtube video into my app?
(7 answers)
Closed 7 years ago.
Okay so I'm looking to play film trailers in my app. The user will press a button, and then it plays the video. I have added the import AVKit and import AVFoundation lines to my file. This is the code I have so far for making the video play:
#IBAction func playTrailerPressed(sender: AnyObject) {
let videoURL = NSURL(string: "https://youtu.be/d88APYIGkjk")
let player = AVPlayer(URL: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.presentViewController(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
This seems to launch an AVPlayerViewController, but doesn't play the video from YouTube. Instead, I get the below:
I have tried both the sharing and embedding link from YouTube, but neither work. If I use a link which has the video file name at the end, it plays it fine, for example: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"- So I know the code works.
Does anyone know if this is possible to use this way with a YouTube video? (I have also tried trailers from IMDb and Apple, but it's the same).
Thanks for your help!
AVPlayer only plays movie files, and YouTube videos aren't directly exposed as movie files at their URL. It looks like the preferred way to handle YouTube videos is to embed a web view into your app. See this page for information from Google on how to do that.
Can the Apple Watch use AVFoundation? More specifically, can AVAudioPlayer and AVAudioRecorder work?
I am trying to make an app that lets you record a sound to the Apple Watch and have it play it back using the audioplayer. Thanks
UPDATE 11/28/15
This answer applies to WatchKit and WatchOS 1.x. Though I have not tested myself, WatchOS 2.x offers different support, including hardware. I can confirm that as of XCode 7.x, the compiler behaves correctly and WatchKit 1.x extensions with calls to AVFoundation won't build.
For WatchOS 1.x and XCode up to 6.x
Despite the fact that AVAudioRecorder and AVAudioPlayer both work in Simulator Apple Watch, they don't actually work on an actual device! I had opened a bug with Apple back on 5/5/15 (once I got to test an App I had written on my actual watch.) My app (a wrist audio recorded) indeed worked beautifully on Simulator. Yet on the actual watch, it would install and run, but the AVAudioRecorder "record" message would simply never toggle into "recording". Interestingly, the code does not throw any exceptions anywhere. It simply does not record!
I received a reply to my Apple Bug today 5/28/15 that "there are no plans to address this" based on "AVFoundation isn't supported on the watch." No word on whether or not Simulator will be updated so that AVFoundation also fails to work.
So, for now, Apple Watch is limited to controlling recording "on the phone" via watch extension to phone messaging which is supported in Apple Watch extensions.
Try using WKAudioFilePlayerItem ?
To use this class to play audio, you need to declare 3 variables:
var audioFile: WKAudioFileAsset!
var audioItem: WKAudioFilePlayerItem!
var audioPlayer: WKAudioFilePlayer!
They have different role inside the program. For audioFile is used to define NSURL. For example, if you have file called "bicycle.mp3", you can define the URL path like this :
let soundPath = NSBundle.mainBundle().pathForResource("bicycle", ofType: "mp3")
print("load file")
when you have a soundpath, you make it a NSURL inside audioFile:
audioFile = WKAudioFileAsset.init(URL: soundPathURL)
When you have a audioFile, you put it inside the audioPlayerItem
audioItem = WKAudioFilePlayerItem.init(asset: audioFile)
When you have audioItem, you put it inside the audioPlayer
`audioPlayer = WKAudioFilePlayer(playerItem: audioItem)`
Finally, you can put the code audioPlayer.play() where you want to play the sound
Enjoy!
Short answer? No. WatchKit doesn't currently offer access to any of the hardware in the Watch.
finally ended up with this:
#IBAction func playButtonTapped() {
let options = [WKMediaPlayerControllerOptionsAutoplayKey : "true"]
let filePath = NSBundle.mainBundle().pathForResource("1button", ofType: "wav")!
let fileUrl = NSURL.fileURLWithPath(filePath)
presentMediaPlayerControllerWithURL(fileUrl, options: options,
completion: { didPlayToEnd, endTime, error in
if let err = error {
print(err.description)
}
})
}