如何在iOS上使用嵌入式HTTP服务器实现视频寻找支持?

6

我有一个客户端iOS应用程序,使用GCDWebServer来服务于存储在设备上我应用程序的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来与Chromecast设备通信,Chromecast接收器应用程序会加载并播放指定URL的视频 - 到目前为止都很好。
我的问题是,我想为当前正在播放的视频实现寻找支持,但是一旦我向媒体通道发送寻找请求,我就会从收到“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 使其可行?我知道问题可以得到解决,因为有几个实时应用程序可以做到这一点。
  • 我需要使用支持其他协议(如HLS或RTSP)的服务器吗?
  • 我需要以特定方式对视频文件进行编码吗?
要参考,我也试过另一个名为 Swifter 的 HTTP 服务器,但遇到了相同的问题。
1个回答

5
iOS的AVPlayer首先请求文件大小,然后向服务器请求数据块,包括请求中所需的范围。在这个答案中,展示了AVPlayer的网络活动,并且响应状态码为206,即Partial Content
因此,我们只需要响应所需的数据块。
webServer?.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self, asyncProcessBlock: { (request, completionBlock) in
  let response = GCDWebServerFileResponse(file: path, byteRange: request.byteRange)
  completionBlock(response)
})

请注意,通过调用request.hasByteRange()检查request.byteRange是否被定义很重要。
使用我提供的代码,我能够使用AVPlayer或Web浏览器播放视频,并且完美地进行了快进/快退操作。

1
我已经按建议修改了我的代码,使用了byteRange,但在我的情况下,消费者不是AVPlayer,而是发送视频数据请求的Chromecast。看起来byteRange.length == -1contentType = nilcontentLength = -1。即使使用hasByteRange(),视频也非常卡顿,我得到了很多这样的错误:[ERROR] Error while writing to socket 18: Broken pipe (32)。 - bizz84
例如,如果文件大小为500,并且有两个请求:
  1. 0-499 - 玩家缓冲足够的数据后,关闭连接(实际上只接收了100字节)
  2. 101-499 - 当缓冲区几乎为空时,播放器开始重新预加载,但不请求已经缓冲的数据。 这解释了断开管道错误。
- Richard Topchii
不确定Chrome如何进行缓冲,但从视频的卡顿情况来看,似乎请求经常发生且缓冲区很小,但数据没有及时接收,以至于视频无法连续播放。如果我省略byteRange,那么播放就没问题,但我就无法寻找,这是我的最初问题。 - bizz84
我想知道App Store上的其他应用是否使用GCDWebServer或其他解决方案。我也尝试过Swifter https://github.com/httpswift/swifter,但是断开管道问题似乎更严重。 - bizz84
1
最终这个解决方案起作用了。感谢您发布它。然而,如果您的网址没有扩展名,此方法将不起作用。该网址可以在Web浏览器中播放视频,但在使用GCDWebServer时,它不会在AVPlayer中播放。 - Mahesh Agrawal
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接