我有一个使用 GCDWebServer 的客户端 iOS 应用程序提供存储在我设备上应用程序的 NSSearchPathDirectory.DocumentDirectory
文件夹中的图像和视频。
在应用程序启动时,我启动一个 GCDWebServer
实例并为我的请求添加一个文件响应处理程序:
self.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerFileRequest.self) { request in
return GCDWebServerFileResponse(file: self.filePathForResponse(request.URL))
}
我可以验证在应用程序运行时我可以从我的设备成功下载文件:
curl -O http://192.168.0.15:8080/files/IMG_1213-1280x720.MOV
我的应用通过将上述 URL 发送到媒体 channel 来与 Chromecast 设备通信,Chromecast 接收器应用加载并播放指定 URL 上的视频 - 到目前为止一切正常。
我的问题是我想为当前播放的视频实现搜索支持,一旦我向媒体 channel 发送搜索请求,我就会从 GCDWebServer
收到“Broken pipe”错误并且视频播放中断。来自服务器的日志如下:
....
[DEBUG] Connection sent 32768 bytes on socket 24
[DEBUG] Connection sent 32768 bytes on socket 24
[ERROR] Error while writing to socket 24: Broken pipe (32)
[DEBUG] Did close connection on socket 24
我对这个问题的最佳理解是,正常播放是有效的,因为它与从头到尾下载文件是一样的,这可以用常规的 GCDWebServerFileResponse
来提供,但是搜索等同于 '跳转到文件的不同部分,我不确定读取这样的文件是否适用于我的配置。
- 有没有一种方法可以配置
GCDWebServer
来完成这项工作?我知道这个问题是可以解决的,因为有几个实时应用程序可以做到这一点。 - 我是否需要使用支持其他协议(protocol)(例如 HLS 或 RTSP)的服务器?
- 我是否需要以特定方式对我的视频文件进行编码?
作为引用,我还尝试了另一个名为 Swifter 的 HTTP 服务器但我遇到了同样的问题。
最佳答案
iOS 的 AVPlayer
首先请求文件大小,然后向服务器请求数据 block ,包括请求中的所需范围。在这个answer ,显示AVPlayer
的网络事件,响应状态码为206
,即Partial Content
。
因此,我们只需要响应所需的数据 block :
webServer?.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self, asyncProcessBlock: { (request, completionBlock) in
let response = GCDWebServerFileResponse(file: path, byteRange: request.byteRange)
completionBlock(response)
})
请注意,检查 request.byteRange
是否通过调用 request.hasByteRange()
定义很重要。
使用我提供的代码,我能够使用 AVPlayer
或网络浏览器播放视频,并且删除/寻找时间完美运行。
关于ios - 如何在 iOS 上使用嵌入式 HTTP 服务器实现 Video Seek 支持?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36651451/