title: How to decode self-delimited opus in iOS
body: <p>I was able to record and play opus using AVFoundation. The problem is I got a custom opus audio file as follows:</p>
  
  <pre><code>| header 1 (1 byte) | opus data 1 (1~255 bytes) | header 2 (1 byte) | opus data 2 (1~255 bytes) | ... | ... |
  </code></pre>
  
  <p>Each header indicates size of the opus data i.e. if header 1 is 200 (Int) then opus data 1 is 200 bytes</p>
  
  <p>So, I am extracting opus data and appending to Data buffer as following:</p>
  
  <pre><code>guard let url = Bundle.main.url(forResource: "test_16kbps", withExtension: "opus") else { return }
  
  do {
  
      let fileData = try Data(contentsOf: url)
  
      while index &lt; fileData.count {
  
          headerData = fileData[index...(index + HEADER_SIZE)]
  
          let opusBytesFromHeader = Int([UInt8](headerData)[0])
  
          start = index + HEADER_SIZE
          end = start + opusBytesFromHeader
  
          opusData = fileData[start..&lt;end]
  
          opusAudioData.append(opusData)
  
          index += (HEADER_SIZE + opusBytesFromHeader)
     }
  
  } catch let err {
     print(err)
  }
  </code></pre>
  
  <p>Then I tried to play using AVAudioPlayer as following</p>
  
  <pre><code>// ... ... ...
  
  playData(audioData: opusAudioData)
  
  // ... ... ...
  
  func playData(audioData: Data){
  
     var avAudioPlayer: AVAudioPlayer?
  
      do {
  
          try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
          try AVAudioSession.sharedInstance().setActive(true)
  
          avAudioPlayer = try AVAudioPlayer.init(data: audioData)
  
          if let player = avAudioPlayer {
              player.play()
          } else {
              print("failed to create player from data")
          }
  
      } catch let error {
          print(error.localizedDescription)
      }
  }
  </code></pre>
  
  <p>Gives error: <code>The operation couldn’t be completed. (OSStatus error 1954115647.)</code>   </p>
  
  <p>I also tried <strong>MobileVLCKit</strong> pod as following:</p>
  
  <pre><code>if let opusFilePath = createNewDirPath() { // creates "foo.opus"
      do {
          try opusAudioData.write(to: opusFilePath)
          let opusMedia = VLCMedia(url: opusFilePath)
          vlcPlayer.media = opusMedia
          vlcPlayer.play()
      } catch let err {
          print(err)
      }
  }
  </code></pre>
  
  <p><strong>Gives following error:</strong></p>
  
  <pre><code>2020-01-05 14:03:41.421270+0900 AppPlay[8695:4077367] creating player instance using shared library
  [mp3 @ 0x10881e600] Failed to read frame size: Could not seek to 40126.
  TagLib: Ogg::File::packet() -- Could not find the requested packet.
  TagLib: Opus::File::read() -- invalid Opus identification header
  </code></pre>
  
  <p>Android team was able to play using libopus (JNI) and AudioTrack. So, I tried to decode opus data using <strong>OpusKit</strong> pod as following:</p>
  
  <pre><code>if let decoded = OpusKit.shared.decodeData(opusData) {
      decodedOpusData.append(decoded)
  } else {
      print("failed to decode")
  }
  </code></pre>
  
  <p>And then tried to play <code>decodedOpusData</code> using AVAudioPlayer but gives same error: <code>The operation couldn’t be completed. (OSStatus error 1954115647.)</code>.   </p>
  
  <p>I don't know what to do to play that audio file (I am new to opus).</p>
  
  <p>About opus data</p>
  
  <blockquote>
    <p>Sample: 16000 | Frame size: 320 (16 * 20 ms) | Channel: 1</p>
  </blockquote>