在iOS中播放自定义.opus音频文件

问题描述 投票:0回答:1

我能够使用AVFoundation录制和播放作品。问题是我得到了一个自定义作品音频文件(来自服务器,也在服务器中处理),如下所示:

| header 1 (1 byte) | opus data 1 (1~255 bytes) | header 2 (1 byte) | opus data 2 (1~255 bytes) | ... | ... |

每个标头指示操作数据的大小,即,如果标头1为200(Int),则操作数据1为200字节

因此,我正在提取作品数据并将其追加到数据缓冲区,如下所示:

guard let url = Bundle.main.url(forResource: "test_16kbps", withExtension: "opus") else { return }

do {

    let fileData = try Data(contentsOf: url)

    while index < fileData.count {

        headerData = fileData[index...(index + HEADER_SIZE)]

        let opusBytesFromHeader = Int([UInt8](headerData)[0])

        start = index + HEADER_SIZE
        end = start + opusBytesFromHeader

        opusData = fileData[start..<end]

        opusAudioData.append(opusData)

        index += (HEADER_SIZE + opusBytesFromHeader)
   }

} catch let err {
   print(err)
}

然后我尝试如下使用AVAudioPlayer播放

// ... ... ...

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)
    }
}

给出错误:The operation couldn’t be completed. (OSStatus error 1954115647.)

我也尝试了MobileVLCKit窗格,如下所示:

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)
    }
}

给出以下错误:

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

Android团队能够使用libopus(JNI)和AudioTrack进行游戏。因此,我尝试使用OpusKit pod解码Opus数据,如下所示:

if let decoded = OpusKit.shared.decodeData(opusData) {
    decodedOpusData.append(decoded)
} else {
    print("failed to decode")
}

然后尝试使用AVAudioPlayer播放decodedOpusData,但出现相同的错误:The operation couldn’t be completed. (OSStatus error 1954115647.)

我不知道如何播放该音频文件(我对歌剧不熟悉)。

关于作品数据

示例:16000 |画面大小:320(16 * 20 ms)|频道:1

ios avfoundation avplayer opus vlckit
1个回答
0
投票

[Per your question,如果您可以获取解码的PCM样本,则可以使用与下面与此C const类似的字节(取自WAV_HEADER_TEMPLATE)]添加RIFF / WAV。>

// Header for a 48 kHz, stereo, 32-bit float WAV.
// http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
static const unsigned char WAV_HEADER_TEMPLATE[44]={
  'R','I','F','F',
  0xFF,0xFF,0xFF,0x7F,  // file size
  'W','A','V','E',
  'f','m','t',' ',      // Chunk ID
  0x10,0x00,0x00,0x00,  // Chunk Size - length of format above
  0x03,0x00,            // Format Code: 1 is PCM, 3 is IEEE float
  0x02,0x00,            // Number of Channels (e.g. 2)
  0x80,0xBB,0x00,0x00,  // Samples per Second, Sample Rate (e.g. 48000)
  0x00,0xDC,0x05,0x00,  // Bytes per second, byte rate = sample rate * bits per sample * channels / 8
  0x08,0x00,            // Bytes per Sample Frame, block align = bits per sample * channels / 8
  0x20,0x00,            // bits per sample (16 for PCM, 32 for float)
  'd','a','t','a',
  0xFF,0xFF,0xFF,0x7F   // size of data section
 };
© www.soinside.com 2019 - 2024. All rights reserved.