Problem with get path to a subfolder in main bundle in AVPlayer - swift

I'm improving the code I have for my project.
I stuck with the process of calling videos by subfolders because the code reads all the mp4 files, it finds.
Applying different codes that I have found on the internet, but I end up breaking all the code without success. I would appreciate help or advice in this regard.
Attached image that shows the location of folders with the different videos that I would like to separate my view basic and intermediate folder
import UIKit
import AVKit
import AVFoundation
class BasicLevel: UIViewController, UITableViewDataSource, UITableViewDelegate, AVPlayerViewControllerDelegate{
var videoArray = [String]()
#IBOutlet weak var videoView: UIView!
#IBOutlet weak var videoTableView: UITableView!
var videoVC = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
videoTableView.delegate = self
videoTableView.dataSource = self
videoView.addSubview(videoVC.view)
videoVC.view.frame = videoView.frame
videoVC.showsPlaybackControls = false
let filemanager = FileManager.default
let path = Bundle.main.resourcePath!
let allItems = try? filemanager.contentsOfDirectory(atPath: path)
for singleItem in allItems! {
if singleItem.hasSuffix("mp4") {
videoArray.append(singleItem)
}
}
if videoArray.count > 0 {
playTopVideo(value: 0)
}
}
func playTopVideo(value: Int) {
let nameComponent = videoArray[value].components(separatedBy: ".")
let name = nameComponent[0]
let path = Bundle.main.path(forResource: name, ofType: "mp4")
let url = URL(fileURLWithPath: path!)
videoVC.player = AVPlayer(url: url)
videoVC.player?.play()
}
}

First of all you are responsible for creating the directory structure of the bundle so don't mess it up.
Secondly use the URL related API.
For example put all mp4 files in a subdirectory named videos. It's crucial that you create a real blue folder rather than a group (yellow) folder.
This would reduce your code to
var videoArray = [URL]()
override func viewDidLoad() {
super.viewDidLoad()
videoTableView.delegate = self
videoTableView.dataSource = self
videoView.addSubview(videoVC.view)
videoVC.view.frame = videoView.frame
videoVC.showsPlaybackControls = false
videoArray = Bundle.main.urls(forResourcesWithExtension: "mp4", subdirectory: "videos")!
playTopVideo(value: 0)
}
func playTopVideo(value: Int) {
let videoURL = videoArray[value]
videoVC.player = AVPlayer(url: videoURL)
videoVC.player?.play()
}

Related

How to detect scrolling to another page in PDF using PDFkit

I'm trying to add current page number
so when the user scrolling to another page it will display
for example
2 of 3 (if the pdf have 3 pages)
for now, I use this code
it will display always 1 of 3
I think PDFkit using UIScrollView
so I need to reach to the ScrollView that way I could detect when scrolling to another page and then increase the current page number
I didn't find any way to reach to scrollview in PDFkit
func showCurrentPageIndex(){
guard let totalPages = pdfContainerView.document?.pageCount else {return}
guard let currentPage = pdfContainerView.currentPage else {return}
guard let currentPageRef = currentPage.pageRef else {return}
let pageIndex = currentPageRef.pageNumber
totalPageNumbers.text = "\(totalPages)"
currentPageIndex.text = "\(pageIndex)"
}
Use a notification (PDFViewPageChanged).
import UIKit
import PDFKit
class ViewController: UIViewController, PDFViewDelegate {
// MARK: - Variables
var totalCount = Int()
// MARK: - IBOutlet
#IBOutlet weak var pdfView: PDFView!
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
let filePath = "Some file document path"
pdfView.document = getDocument(path: filePath)
if let total = pdfView.document?.pageCount {
totalCount = total
}
pdfView.backgroundColor = .lightGray
pdfView.autoScales = true
pdfView.displayMode = .singlePageContinuous
pdfView.usePageViewController(true, withViewOptions: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
/* notification */
NotificationCenter.default.addObserver (self, selector: #selector(handlePageChange), name: Notification.Name.PDFViewPageChanged, object: nil)
}
func getDocument(path: String) -> PDFDocument? {
let pdfURL = URL(fileURLWithPath: filePath)
let document = PDFDocument(url: pdfURL)
return document
}
}

Play video from url without extension swift

I want to play video from url returns from service, url doesn't have extension, so it doesn't work. what should I do?
xcode9 swift 4
import AVKit
import AVFoundation
import MediaPlayer
import AudioToolbox
class ViewController: UIViewController {
#IBOutlet weak var player_View: UIView!
let videoURL = URL(string: "http://45.58.42.105:82/Handlers/ImageHandler.ashx?fileReference=67f0dce7-a5f5-4894-a8fd-5996f135626c");
var playerVC = AVPlayerViewController()
var playerView = AVPlayer()
var urlStr = "";
override func viewDidLoad() {
super.viewDidLoad()
self.playVideo();
}
func playVideo() {
self.playerView = AVPlayer(url: videoURL!)
self.playerVC.player = playerView
self.player_View.addSubview(self.playerVC.view)
playerVC.view.frame = self.player_View.frame
playerView.play()
}
}

How Can I Change a String Using Remote Config?

I'm creating an app that plays a sound when a button is clicked. It consists of UIButton to play the sound, UIImageView to display the associated image, and another UIButton which I'm using like a label to describe the button. I want to be able to configure all three parameters so I can change them remotely from Firebase. So far I figured out how to change the label, but I want to be able to change the URL that the sound and image load from. Here is my code:
import UIKit
import Firebase
import AVKit
class FirebaseViewController: UIViewController, AVAudioPlayerDelegate {
//These variables are for my sound when I click a button
var firesound1 = AVPlayer()
var firesound2 = AVPlayer()
var firesound3 = AVPlayer()
//These outlets reference the labels(UIButton) and UIImageView in the storyboard
#IBOutlet weak var firelabel1: UIButton!
#IBOutlet weak var firelabel2: UIButton!
#IBOutlet weak var firelabel3: UIButton!
#IBOutlet weak var fireimage1: UIImageView!
#IBOutlet weak var fireimage2: UIImageView!
#IBOutlet weak var fireimage3: UIImageView!
func updateViewWithRCValues() {
//These remote config options allow me to change the text of the UIButton, which here I'm using like a UILabel
firelabel1.setTitle(buttonLabel1, for: .normal)
let buttonLabel2 = RemoteConfig.remoteConfig().configValue(forKey: "label2").stringValue ?? ""
firelabel2.setTitle(buttonLabel2, for: .normal)
let buttonLabel3 = RemoteConfig.remoteConfig().configValue(forKey: "label3").stringValue ?? ""
firelabel3.setTitle(buttonLabel3, for: .normal)
let url = RemoteConfig.remoteConfig().configValue(forKey: "url1").stringValue ?? ""
firelabel3.setTitle(buttonLabel3, for: .normal)
}
func setupRemoteConfigDefaults() {
let defaultValues = [
"label1": "" as NSObject,
"label2": "" as NSObject,
"label3": "" as NSObject
]
RemoteConfig.remoteConfig().setDefaults(defaultValues)
}
func fetchRemoteConfig() {
// Remove this before production!!
let debugSettings = RemoteConfigSettings(developerModeEnabled: true)
RemoteConfig.remoteConfig().configSettings = debugSettings!
RemoteConfig.remoteConfig().fetch(withExpirationDuration: 0) { [unowned self] (status, error) in guard error == nil else {
print ("Error fetching remote values: \(String(describing: error))")
return
}
print("Retrieved values from the cloud")
RemoteConfig.remoteConfig().activateFetched()
self.updateViewWithRCValues()
}
}
override func viewDidLoad() {
super.viewDidLoad()
setupRemoteConfigDefaults()
fetchRemoteConfig()
//This code loads an image from a url into a UIImageView. I want to be able to configure the url like a parameter so I can change the url from the firebase website.
let url = URL(string: "https://ichef-1.bbci.co.uk/news/976/media/images/83351000/jpg/_83351965_explorer273lincolnshirewoldssouthpicturebynicholassilkstone.jpg")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if (error != nil)
{
print("ERROR")
}
else
{
var documentsDirectory: String?
var paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if paths.count > 0
{
documentsDirectory = paths [0]
let savePath = documentsDirectory! + "/ImageOne"
FileManager.default.createFile(atPath: savePath, contents: data, attributes: nil)
DispatchQueue.main.async
{
self.fireimage1.image = UIImage(named: savePath)
}
}
}
}
task.resume()
}
//This code plays the sounds. I also want to be able to configure the url like a parameter.
#IBAction func soundpressed1(_ sender: Any) {
let sound1 = AVPlayerItem(url: URL(string: "https://firebasestorage.googleapis.com/v0/b/mlg-soundboard-2018-edition.appspot.com/o/hitmarker.mp3?alt=media&token=e5d342d6-4074-4c50-ad9d-f1e41662d9e9")!)
firesound1 = AVPlayer(playerItem: sound1)
firesound1.play()
}
override func didReceiveMemoryWarning() {
}
}
Basically I want to be able to swap out the URLs with Remote Config.
You can either create separate keys in Remote config for Text, Sound URL and Image URL.
Or you can create a key called button_config and supply all the three params in a JSON
button_config = {"text" : "My button label", "sound_url" : "https://foo.com/sound.mp3", "image_url" : "https://foo.com/image.png"}

Trigger sound play() with NSSpeechRecognizer Swift

I'm trying to trigger a sound after I say a word. The speech recognizer recognizes the word when I say it and I've set it up so it puts out a string each time I say the command. What I'd like to do is trigger a sound after I say that specific word. This is what I have so far.
import Cocoa
import AVFoundation
class ViewController: NSViewController, NSSpeechRecognizerDelegate {
var ping = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("ping", ofType: "mp3")!)
var pingAudioPlayer = AVAudioPlayer()
var sr = NSSpeechRecognizer()
#IBOutlet var output: NSTextView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
pingAudioPlayer = AVAudioPlayer(contentsOfURL: ping, error: nil)
sr.delegate = self
sr.commands = ["Ping", "Ping Mac"]
sr.startListening()
}
func speechRecognizer(sender: NSSpeechRecognizer, didRecognizeCommand command: AnyObject?) {
output!.string! += "\(command)\n"
pingAudioPlayer.play()
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
UPDATE:
import Cocoa
import AVFoundation
class ViewController: NSViewController, NSSpeechRecognizerDelegate {
var ping = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("ping", ofType: "mp3")!)
let pingAudioPlayer = AVAudioPlayer()
var sr = NSSpeechRecognizer()
#IBOutlet var output: NSTextView?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
sr.delegate = self
sr.commands = ["Ping", "Ping Mac"]
sr.startListening()
}
func speechRecognizer(sender: NSSpeechRecognizer, didRecognizeCommand command: AnyObject?) {
output!.string! += "\(command)\n"
var pingAudioPlayer = AVAudioPlayer(contentsOfURL: ping, error: nil)
pingAudioPlayer.prepareToPlay()
pingAudioPlayer.play()
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
Not sure why the audio player is not playing the sound once the word is recognized. Any ideas?
You aren't telling the audio player which sound to play. Try this:
func speechRecognizer(sender: NSSpeechRecognizer, didRecognizeCommand command: AnyObject?) {
do{
let pingAudioPlayer = try AVAudioPlayer(contentsOfURL:ping)
pingAudioPlayer.prepareToPlay()
pingAudioPlayer.play()
}catch {
print("Error getting the audio file")
}
}

Save and Load PDF in my App

I am downloading a .PDF file from a URL into a webview. It works fine , but because the pdf get updated mid month. I would like to download that file on the first of every month into my app, then the rest of the month load that saved file from the app rather than the web. Thank you for any help. I am using Swift.
following is my code so far :
import UIKit
import Social
// var justOnceThree:Bool = true
class KeyPagesViewController: UIViewController {
#IBOutlet weak var photoButton: UIButton!
#IBOutlet weak var baseKeypagesLabel: UILabel!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var keyPages: UIWebView!
var urlFra = "http://someURL.pdf"
var urlLhr = "http://someURL.pdf"
let requestURL = NSURL()
override func viewDidAppear(animated: Bool) {
PhotoButton()
}
override func viewDidLoad() {
super.viewDidLoad()
animationtitle()
let sharedDefaults = NSUserDefaults(suiteName: "group.birkyboy.TodayExtensionSharingDefaults")
var based = sharedDefaults!.objectForKey("base") as? String
if based == "HNL" {
let requestURL = NSURL(string:self.urlHnl)
let request = NSURLRequest(URL: requestURL!)
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
self.keyPages.hidden = false
self.keyPages.loadRequest(request)
self.baseKeypagesLabel.text = "HONOLULU"
}
if based == "IAH" {
let requestURL = NSURL(string:self.urlIah)
let request = NSURLRequest(URL: requestURL!)
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
self.keyPages.hidden = false
self.keyPages.loadRequest(request)
self.baseKeypagesLabel.text = "HOUSTON"
}
}
You can save the PDF in the users Documents folder. See "iOS Standard Directories: Where Files Reside" in the Apple documentation. There are various ways to get the PDF from a URL. See NSInputStream for one way to do it. Once you have it (as an NSData object, for example), you can save it as a file.