制作MacOS应用程序时无法在Swift中播放URL中的音频

制作MacOS应用程序时无法在Swift中播放URL中的音频,swift,xcode,macos,audio,avplayer,Swift,Xcode,Macos,Audio,Avplayer,所以,这一定是我遇到的最困难的问题之一。 我所要做的就是使用Swift和Xcode 11.4.1从URL在MacOS应用程序中播放音频 我已经试过了 import AVFoundation var player : AVPlayer let url = URL.init(string: "https://api.fetchdev.host/m.mp3") player = AVPlayer(url: url!) player.pla

所以,这一定是我遇到的最困难的问题之一。 我所要做的就是使用Swift和Xcode 11.4.1从URL在MacOS应用程序中播放音频

我已经试过了

    import AVFoundation

    var player : AVPlayer
    let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    player = AVPlayer(url: url!)

    player.play()
还有这个

    var player : AVPlayer
    let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    player = AVPlayer(url: url!)
    let playerItem = AVPlayerItem.init(url: url!)
    player = AVPlayer.init(playerItem: playerItem)

    player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerQueue = AVQueuePlayer()
    let playerItem = AVPlayerItem.init(url: url!)
    playerQueue.insert(playerItem, after: nil)
    playerQueue.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerItem = AVPlayerItem(url: url!)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
    player.play()
try AVAudioSession.sharedInstance().setCategory(.playback, mode.default)
        try AVAudioSession.sharedInstance().setActive(true)
        player = try AVPlayer(url: url as URL)
        guard let player = player
            else
        {
            return
        }
        player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    do{
        let audioPlayer = try AVAudioPlayer(contentsOf: url!)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch{
        print(error)
    }
还有这个

    var player : AVPlayer
    let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    player = AVPlayer(url: url!)
    let playerItem = AVPlayerItem.init(url: url!)
    player = AVPlayer.init(playerItem: playerItem)

    player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerQueue = AVQueuePlayer()
    let playerItem = AVPlayerItem.init(url: url!)
    playerQueue.insert(playerItem, after: nil)
    playerQueue.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerItem = AVPlayerItem(url: url!)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
    player.play()
try AVAudioSession.sharedInstance().setCategory(.playback, mode.default)
        try AVAudioSession.sharedInstance().setActive(true)
        player = try AVPlayer(url: url as URL)
        guard let player = player
            else
        {
            return
        }
        player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    do{
        let audioPlayer = try AVAudioPlayer(contentsOf: url!)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch{
        print(error)
    }
还有这个

    var player : AVPlayer
    let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    player = AVPlayer(url: url!)
    let playerItem = AVPlayerItem.init(url: url!)
    player = AVPlayer.init(playerItem: playerItem)

    player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerQueue = AVQueuePlayer()
    let playerItem = AVPlayerItem.init(url: url!)
    playerQueue.insert(playerItem, after: nil)
    playerQueue.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerItem = AVPlayerItem(url: url!)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
    player.play()
try AVAudioSession.sharedInstance().setCategory(.playback, mode.default)
        try AVAudioSession.sharedInstance().setActive(true)
        player = try AVPlayer(url: url as URL)
        guard let player = player
            else
        {
            return
        }
        player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    do{
        let audioPlayer = try AVAudioPlayer(contentsOf: url!)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch{
        print(error)
    }
还有这个

    var player : AVPlayer
    let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    player = AVPlayer(url: url!)
    let playerItem = AVPlayerItem.init(url: url!)
    player = AVPlayer.init(playerItem: playerItem)

    player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerQueue = AVQueuePlayer()
    let playerItem = AVPlayerItem.init(url: url!)
    playerQueue.insert(playerItem, after: nil)
    playerQueue.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerItem = AVPlayerItem(url: url!)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
    player.play()
try AVAudioSession.sharedInstance().setCategory(.playback, mode.default)
        try AVAudioSession.sharedInstance().setActive(true)
        player = try AVPlayer(url: url as URL)
        guard let player = player
            else
        {
            return
        }
        player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    do{
        let audioPlayer = try AVAudioPlayer(contentsOf: url!)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch{
        print(error)
    }
(MacOS不支持音频会话)

还有这个

    var player : AVPlayer
    let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    player = AVPlayer(url: url!)
    let playerItem = AVPlayerItem.init(url: url!)
    player = AVPlayer.init(playerItem: playerItem)

    player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerQueue = AVQueuePlayer()
    let playerItem = AVPlayerItem.init(url: url!)
    playerQueue.insert(playerItem, after: nil)
    playerQueue.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    let playerItem = AVPlayerItem(url: url!)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
    player.play()
try AVAudioSession.sharedInstance().setCategory(.playback, mode.default)
        try AVAudioSession.sharedInstance().setActive(true)
        player = try AVPlayer(url: url as URL)
        guard let player = player
            else
        {
            return
        }
        player.play()
let url = URL.init(string: "https://api.fetchdev.host/m.mp3")
    do{
        let audioPlayer = try AVAudioPlayer(contentsOf: url!)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }catch{
        print(error)
    }
(此处的错误是“错误域=NSOSStatusErrorDomain代码=2003334207”(null)”)

还有一些我不喜欢的第三方cocoapods。 所有这些都不起作用。 我的info.plist中也有:

<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict/>
</dict>
我找不到关于至少一个错误的任何信息。
非常感谢您的帮助。

以下代码在swift中实现了一个适用于macOS的avplayer。它可以在Xcode中运行,方法是添加一个名为“main.swift”的新文件并将代码复制/粘贴到其中。此外,您需要删除预先存在的AppDelegate以避免重复符号

import Cocoa
import AVKit
import AVFoundation

class AppDelegate: NSObject, NSApplicationDelegate {
var window:NSWindow!
var playerView:AVPlayerView!

@objc func openAction(_ sender:AnyObject ) {
let op = NSOpenPanel()    
    op.title                   = "Choose a file"
    op.showsResizeIndicator   = true
    op.showsHiddenFiles        = false
    op.canChooseDirectories   = true
    op.canCreateDirectories    = true
    op.allowsMultipleSelection = false
    op.allowedFileTypes        = ["aiff","mp4", "mpg"]

  if (op.runModal() == NSApplication.ModalResponse.OK) {
    let player = AVPlayer(url:op.url!)
    playerView.player = player
    window.setTitleWithRepresentedFilename(op.url!.lastPathComponent)
  } else {
   return
 }
}

func buildMenu() {
 let mainMenu = NSMenu()
 NSApp.mainMenu = mainMenu
 // **** App menu **** //
 let appMenuItem = NSMenuItem()
 mainMenu.addItem(appMenuItem)
 let appMenu = NSMenu()
 appMenuItem.submenu = appMenu
 appMenu.addItem(withTitle: "Quit", action:#selector(NSApplication.terminate), keyEquivalent: "q") 
}
    
func buildWnd() {
    
let _wndW : CGFloat = 500
let _wndH : CGFloat = 400

 window = NSWindow(contentRect:NSMakeRect(0,0,_wndW,_wndH),styleMask:[.titled, .closable, .miniaturizable, .resizable], backing:.buffered, defer:false)
 window.center()
 window.title = "AVPlayer"
 window.makeKeyAndOrderFront(window)

// **** AVPlayerView **** //
playerView = AVPlayerView(frame:NSMakeRect( 0, 60, _wndW, _wndH - 60))
playerView.autoresizingMask = [.width, .height]
window.contentView!.addSubview (playerView)

// **** Open Button **** //
let myBtn = NSButton (frame:NSMakeRect( 30, 10, 125, 30 ))
 myBtn.bezelStyle = .rounded
 myBtn.autoresizingMask = [.maxXMargin,.maxYMargin]
 myBtn.title = "Open file. . ."
 myBtn.action = #selector(self.openAction(_:))
 window.contentView!.addSubview (myBtn)

// **** Quit btn **** //
let quitBtn = NSButton (frame:NSMakeRect( _wndW - 50, 10, 40, 40 ))
 quitBtn.bezelStyle = .circular
 quitBtn.autoresizingMask = [.minXMargin,.maxYMargin]
 quitBtn.title = "Q"
 quitBtn.action = #selector(NSApplication.terminate)
 window.contentView!.addSubview(quitBtn)
}
 
func applicationDidFinishLaunching(_ notification: Notification) {
 buildMenu()
 buildWnd()
}

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
 return true
}

}
let appDelegate = AppDelegate()

// **** main.swift **** //
let app = NSApplication.shared
app.delegate = appDelegate
app.setActivationPolicy(.regular)
app.activate(ignoringOtherApps:true)
app.run()


所以,正如Matt在评论中所说的,我的问题是将Player变量设置为局部变量,而不是将其存储为属性


这就是解决方案:

你能展示真实的代码吗?代码不只是漂浮在半空中;除实例属性外,所有内容都必须位于函数内部。请显示实际的代码,以便我们可以看到所有这些代码行是否都在正确的位置。谢谢@马特,恐怕没有什么可展示的。是的,代码不会漂浮在半空中,但我为什么要在这里放置不相关的信息呢?除此之外,我的脚本还有一个iAction,它调用一个函数,包含所有这些代码。该功能必须开始发挥作用。如果我能向你提供任何进一步的细节,请告诉我。谢谢好吧,如果你知道什么是不相关的,你可能不会有这个问题。例如,看看您的第一个代码。看看第一行,
var-player:AVPlayer
。我知道如果它在IBAction函数中,或者在任何其他函数中,播放都会失败。但是我不知道你是否知道这一点,所以我不能假设你对代码的描述到底意味着什么。@matt,很抱歉让你感到困惑。iAction只调用以下函数:func play(){}。谢谢,如果这是真的,并且
func play
确实包含了您正在显示的所有代码,那么您得到的正是预期的结果-没有声音。例如,见