在我的iOS应用程序中与我的外部配件通信以播放流中的视频



在我的iOS应用程序中,我需要使用外部配件框架播放视频。框架将通过委托方法提供流。但是我找不到从字节流播放的播放器。请推荐解决此问题的最佳方法

(
  • void(stream:(NSStream*(theStream handleEvent:(NSStreamEvent(streamEvent { }

有两种方法,第一种方法是将字节流保存在本地临时文件中,然后使用 AVAsset 播放。

let url = URL(fileURLWithPath: filePath)
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: ["playable"])
player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
playerLayer.videoGravity = .resizeAspect
view.layer.addSublayer(playerLayer)

如果您不想将视频保存在设备中,您可以在应用程序中制作HTTPServer,并使用AVURLAsset与AVPlayer一起播放。下面是一个使用 GCD Web 服务器的示例,请注意,服务器需要接受范围请求才能与 AVPlayer 和 完美配合。

self.webServer = GCDWebServer()
self.webServer!.addDefaultHandler(forMethod: "GET", request: GCDWebServerRequest.self, asyncProcessBlock: {(request,completionBlock) in
let path = Bundle.main.path(forResource: "sample", ofType: "mp4")
var attr:[FileAttributeKey : Any]
do {
attr = try FileManager.default.attributesOfItem(atPath: path!)
}
catch{
completionBlock(GCDWebServerResponse(statusCode: 500))
return
}
let fileSize = attr[FileAttributeKey.size] as! UInt64
if (request.hasByteRange()){
let handler = FileHandle.init(forReadingAtPath: path!)
handler?.seek(toFileOffset: UInt64(request.byteRange.lowerBound))
var response:GCDWebServerDataResponse
if(request.byteRange.upperBound <= -1){
response = GCDWebServerDataResponse(data: (handler?.readDataToEndOfFile())!, contentType: "video/mp4")
}
else{
response = GCDWebServerDataResponse(data: (handler?.readData(ofLength: request.byteRange.length))!, contentType: "video/mp4")
}
response.statusCode = 206
response.setValue("bytes (request.byteRange.lowerBound)-(request.byteRange.upperBound-1)/(fileSize)", forAdditionalHeader: "Content-Range")
response.setValue("bytes", forAdditionalHeader: "Accept-Ranges")
response.setValue("(request.byteRange.length)", forAdditionalHeader: "Content-Length")
response.setValue("video/mp4", forAdditionalHeader: "Content-Type")
response.setValue("keep-alive", forAdditionalHeader: "Connection")
completionBlock(response)
return
}
else {
let handler = FileHandle.init(forReadingAtPath: path!)
let response = GCDWebServerDataResponse(data: (handler?.readDataToEndOfFile())!, contentType: "video/mp4")
response.setValue("bytes", forAdditionalHeader: "Accept-Ranges")
response.setValue("keep-alive", forAdditionalHeader: "Connection")
completionBlock(response)
return
}
})
self.webServer!.start(withPort: 8080, bonjourName: "")
GCDWebServer.setLogLevel(0)

然后,您可以将 AVPlayer 设置为使用本地 Web 服务器来播放视频。

let asset = AVURLAsset(url: URL(string: "http://localhost:8080/")!)
let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: ["playable"])
player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = CGRect(x: 0, y: 0, width: viewPlayer.frame.width, height: viewPlayer.frame.height)
playerLayer.videoGravity = .resizeAspect
viewPlayer.layer.addSublayer(playerLayer)
self.view.layoutIfNeeded()
player!.play()

最新更新