2016-04-27 7 views
11

में कनवर्ट करें मेरे पास NSSound ऑब्जेक्ट्स हैं जिन्हें मैं AVAudioPlayer उदाहरणों में कनवर्ट करना चाहता हूं। मेरे पास NSSound ऑब्जेक्ट्स से जुड़े फ़ाइल पथ (NSURL एस) हैं, लेकिन मूल फ़ाइल मौजूद नहीं हो सकती है।NSSound को AVAudioPlayer

class SoundObj: NSObject { 
    var path: NSURL? 
    var sound: NSSound? 
    var player: AVAudioPlayer 
} 

let aSound = SoundObj() 
aSound.path = NSURL(fileURLWithPath: "file:///path/to/sound.m4a") 
aSound.sound = NSSound(contentsOfURL: aSound.path)! 

do { 
    try aSound.player = AVAudioPlayer(contentsOfURL: aSound.path) 
} catch { 
    // perhaps use AVAudioPlayer(data: ...)? 
} 

मैं एक AVAudioPlayer उदाहरण के लिए एक NSSound वस्तु परिवर्तित: यहाँ क्या मैं अब तक किया है?

+0

यदि ऑडियो फ़ाइल मौजूद नहीं है तो क्या यह लाइन क्रैश नहीं होगी? 'aSound.sound = NSSound (contentOfURL: aSound.path)!' – brimstone

+0

हां, लेकिन इस मामले के लिए '.ound 'कभी शून्य नहीं है। – Matt

+0

ईमानदारी से, मुझे नहीं लगता कि आप एनएसएसएंड से ध्वनि डेटा प्राप्त कर सकते हैं। – brimstone

उत्तर

2

इसलिए मुझे NSSound ऑब्जेक्ट से यूआरएल प्राप्त करने के लिए सार्वजनिक इंटरफ़ेस नहीं दिखाई दिया, इसलिए मैं private headers के माध्यम से खोदने के लिए देख रहा था कि मुझे क्या मिल सकता है। निजी उदाहरण विधि url और _url हैं जो NSSound के URL को वापस कर देते हैं। संभवतः ये NSURL इवर या संपत्ति के लिए गेटर्स हैं।

उद्देश्य-सी के साथ यह आसान होगा: हम केवल नए इंटरफ़ेस या एक्सटेंशन में विधियां जोड़ देंगे। साथ शुद्ध स्विफ्ट बातें एक छोटे से जटिल काम है, और हम एक ऑब्जेक्टिव-सी प्रोटोकॉल के माध्यम से एक्सेसर बेनकाब करने के लिए की जरूरत है:

@objc protocol NSSoundPrivate { 
    var url: NSURL? { get } 
} 

url के बाद से एक उदाहरण विधि है, तो आप func url() -> NSURL? के बजाय एक चर का उपयोग कर के साथ बेहतर परिणाम प्राप्त कर सकते हैं। आपका मिलेज भिन्न हो सकता है: केवल पढ़ने-योग्य संपत्ति के व्यवहार को अनुकरण करने के लिए var का उपयोग करना मेरे लिए काम करना प्रतीत होता है।

मैं AVAudioPlayer पर एक विस्तार में एक नई सुविधा प्रारंभकर्ता लिखा है:

extension AVAudioPlayer { 
    convenience init?(sound: NSSound) throws {  
     let privateSound = unsafeBitCast(sound, NSSoundPrivate.self)  
     guard let url = privateSound.url else { return nil } 
     do { 
      try self.init(contentsOfURL: url) 
     } catch { 
      throw error 
     } 
    } 
} 

उपयोग:

let url = NSURL(...)  
if let sound = NSSound(contentsOfURL: url, byReference: true) { 
    do { 
     let player = try AVAudioPlayer(sound: sound) 
     player?.play() 
    } catch { 
     print(error) 
    }   
} 

ivars में NSData से संबंधित कुछ भी, उदाहरण के तरीकों, और के गुणों को खोजने के लिए प्रयास करने के बाद एक एनएसएसएंड, मैं इस निष्कर्ष पर आया हूं कि NSSound को प्रारंभ करने के लिए जो कुछ भी आप उपयोग करते हैं उसका डेटा हिस्सा क्लास के कार्यान्वयन में कहीं भी खराब हो जाता है, और यह उपलब्ध नहीं है यूआरएल है

संबंधित मुद्दे