【发布时间】:2015-06-24 22:52:57
【问题描述】:
目前下面的代码可以流式传输本地 mp3 文件,所以如果我调用
audio.scheduleFile(NSBundle.mainBundle().URLForResource("Moon River", withExtension: "mp3")!)
它将正确播放本地文件。现在我希望能够流式传输非本地 url。
我需要做什么才能让我流式传输 mp3 网址?
class Audio: NSObject {
var graph: AUGraph
var filePlayerAU: AudioUnit
var filePlayerNode: AUNode
var outputAU: AudioUnit
var fileID: AudioFileID
var currentFrame: Int64
override init () {
graph = AUGraph()
filePlayerAU = AudioUnit()
filePlayerNode = AUNode()
outputAU = AudioUnit()
fileID = AudioFileID()
currentFrame = 0
super.init()
NewAUGraph(&graph)
// Add file player node
var cd = AudioComponentDescription(componentType: OSType(kAudioUnitType_Generator),
componentSubType: OSType(kAudioUnitSubType_AudioFilePlayer),
componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
componentFlags: 0, componentFlagsMask: 0)
AUGraphAddNode(graph, &cd, &filePlayerNode)
// Add output node
var outputNode = AUNode()
cd.componentType = OSType(kAudioUnitType_Output)
cd.componentSubType = OSType(kAudioUnitSubType_RemoteIO)
AUGraphAddNode(graph, &cd, &outputNode)
// Graph must be opened before we can get node info!
AUGraphOpen(graph)
AUGraphNodeInfo(graph, filePlayerNode, nil, &filePlayerAU)
AUGraphNodeInfo(graph, outputNode, nil, &outputAU)
AUGraphConnectNodeInput(graph, filePlayerNode, 0, outputNode, 0)
AUGraphInitialize(graph)
registerCallbackForAU(filePlayerAU, nil)
}
func scheduleFile(url: NSURL) {
AudioFileOpenURL(url, 1, 0, &fileID)
// Step 1: schedule the file(s)
// kAudioUnitProperty_ScheduledFileIDs takes an array of AudioFileIDs
var filesToSchedule = [fileID]
AudioUnitSetProperty(filePlayerAU,
AudioUnitPropertyID(kAudioUnitProperty_ScheduledFileIDs),
AudioUnitScope(kAudioUnitScope_Global), 0, filesToSchedule,
UInt32(sizeof(AudioFileID)))
}
func scheduleRegion() {
// Step 2: Schedule the regions of the file(s) to play
// Swift forces us to fill out the structs completely, even if they are not used
let smpteTime = SMPTETime(mSubframes: 0, mSubframeDivisor: 0,
mCounter: 0, mType: 0, mFlags: 0,
mHours: 0, mMinutes: 0, mSeconds: 0, mFrames: 0)
var timeStamp = AudioTimeStamp(mSampleTime: 0, mHostTime: 0, mRateScalar: 0,
mWordClockTime: 0, mSMPTETime: smpteTime,
mFlags: UInt32(kAudioTimeStampSampleTimeValid), mReserved: 0)
var region = ScheduledAudioFileRegion()
region.mTimeStamp = timeStamp
region.mCompletionProc = nil
region.mCompletionProcUserData = nil
region.mAudioFile = fileID
region.mLoopCount = 0
region.mStartFrame = currentFrame
region.mFramesToPlay = UInt32.max
AudioUnitSetProperty(filePlayerAU,
AudioUnitPropertyID(kAudioUnitProperty_ScheduledFileRegion),
AudioUnitScope(kAudioUnitScope_Global), 0, ®ion,
UInt32(sizeof(ScheduledAudioFileRegion)))
// Step 3: Prime the file player
var primeFrames: UInt32 = 0
AudioUnitSetProperty(filePlayerAU,
AudioUnitPropertyID(kAudioUnitProperty_ScheduledFilePrime),
AudioUnitScope(kAudioUnitScope_Global), 0, &primeFrames,
UInt32(sizeof(UInt32)))
// Step 4: Schedule the start time (-1 = now)
timeStamp.mSampleTime = -1
AudioUnitSetProperty(filePlayerAU,
AudioUnitPropertyID(kAudioUnitProperty_ScheduleStartTimeStamp),
AudioUnitScope(kAudioUnitScope_Global), 0, &timeStamp,
UInt32(sizeof(AudioTimeStamp)))
}
}
【问题讨论】:
-
可以先获取base64服务器“data:audio/mp3;base64”,传给“NSData”,这样就可以在普通的AVPlayer上播放了。