【问题标题】:How to implement Video Seek support with an embedded HTTP server on iOS?如何在 iOS 上使用嵌入式 HTTP 服务器实现 Video Seek 支持?
【发布时间】:2016-08-07 16:20:08
【问题描述】:

我有一个客户端 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 加载和播放视频 - 到目前为止一切正常。

我的问题是我想为当前播放的视频实现寻求支持,并且一旦我向媒体频道发送寻求请求,我就会从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 来完成这项工作?我知道这个问题是可以解决的,因为有几个实时应用可以做到这一点。
  • 我是否需要使用支持 HLS 或 RTSP 等其他协议的服务器?
  • 我是否需要以特定方式对视频文件进行编码?

作为参考,我还尝试了另一个名为 Swifter 的 HTTP 服务器,但我遇到了同样的问题。

【问题讨论】:

    标签: ios webserver video-streaming gcdwebserver


    【解决方案1】:

    iOS'AVPlayer 首先请求文件大小,然后向服务器请求数据块,包括请求中所需的范围。在这个answer中,显示了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.byteRange 是否通过调用request.hasByteRange() 定义很重要。

    使用我提供的代码,我能够使用AVPlayer 或网络浏览器播放视频,并且擦洗/寻找时间效果很好。

    【讨论】:

    • 我已按照建议修改了我的代码以使用byteRange,但在我的情况下,消费者不是 AVPlayer,而是 Chromecast 发送视频数据请求。似乎 byteRange.length == -1,contentType = nil 和 contentLength = -1。即使将它与hasByteRange() 一起使用,视频也很不稳定,我得到很多:[ERROR] Error while writing to socket 18: Broken pipe (32)
    • 我观察到,客户端(AVPlayer 或 Chrome)如何消费内容:在初始请求获取视频大小后,他们从头开始请求整个视频。在客户端缓冲了足够的数据后,它停止接收它会关闭连接,因此会出现管道损坏错误。当客户端需要更多数据时(即播放器已经播放了几乎所有缓冲的视频或用户开始清理到不同的位置),客户端开始新的请求,字节范围不是从零开始,而是在文件末尾结束。
    • 例如文件大小为500,有两个请求: 1. 0-499 - 播放器缓存足够数据后关闭连接(实际上只收到100字节) 2. 101 -499 - 当缓冲区几乎为空时,播放器再次开始预加载,但不请求已经缓冲的数据。这解释了损坏的管道错误
    • 不确定 Chrome 是如何进行缓冲的,但从视频的断断续续来看,似乎经常发出请求并且对于小缓冲区,但数据接收速度不够快,因此视频可以连续播放.如果我省略byteRange,那么播放就可以了,但我无法找到原来的问题。
    • 这个解决方案终于奏效了。感谢您发布此内容。但是,当您的网址没有扩展名时,这不起作用。该网址在网络浏览器上播放视频,但在这种情况下,它不会在使用 GCDWebServer 的 AVPlayer 中播放
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 2015-10-07
    • 2016-05-03
    • 1970-01-01
    • 2012-04-16
    • 2014-03-23
    • 2012-01-18
    • 2011-11-08
    相关资源
    最近更新 更多