Search code examples
swiftgoogle-cast

Lags on specific video running on local server (iOS)


Based on example project from google build simple player app for play video on device. Added GCDWebServer lib for local streaming. All works fine, except 1 video. It is little bit laggy. On other players from AppStore this video was played perfectly.

Here code how I setup GCKCastContext and start playing on Chromecast:

static func setup() {
    let options = GCKCastOptions(discoveryCriteria: GCKDiscoveryCriteria(applicationID: kReceiverAppID))
    options.physicalVolumeButtonsWillControlDeviceVolume = true
    GCKCastContext.setSharedInstanceWith(options)


    let logFilter = GCKLoggerFilter()
    logFilter.minimumLevel = .error
    GCKLogger.sharedInstance().filter = logFilter
    GCKLogger.sharedInstance().delegate = shared

    shared.sessionManager.add(shared)
}

func generateMediaInfo(url: URL) -> GCKMediaInformation {
    let builder = GCKMediaInformationBuilder(contentURL: url)

    builder.streamType = .live
    if url.isFileURL, let mimeType = mimeTypes[url.pathExtension] {
        builder.contentType = mimeType
    }
    builder.metadata = GCKMediaMetadata(metadataType: .movie)
    builder.mediaTracks = nil
    builder.textTrackStyle = buildTextStyle()

    let mediaInfo = builder.build()
    return mediaInfo
}

func buildTextStyle() -> GCKMediaTextTrackStyle {
    let style = GCKMediaTextTrackStyle.createDefault()
    style.windowType = .roundedCorners
    style.windowColor = GCKColor(red: 0, green: 0, blue: 0, alpha: 0.7)
    return style
}

func playURL(_ url: URL, position: Double = 0) {
    let options = GCKMediaLoadOptions()
    options.playPosition = position

    let url = ChromecastServer.startServer(url.path) // builded with GCDWebServer, returns local server url
    let mediaInfo = generateMediaInfo(url: url!)

    if let client = sessionManager.currentCastSession?.remoteMediaClient {
        performAsyncIn(.main) {
            client.loadMedia(mediaInfo, with: options)
        }
    }
}

Solution

  • It's because I'm not properly respond to Content-Range request. Fixed version:

    server = GCDWebServer()
    server?.addHandler(forMethod: "GET", path: "/chromecast_video", request: GCDWebServerRequest.self, processBlock: { (req) -> GCDWebServerResponse? in
        var resp: GCDWebServerFileResponse? = GCDWebServerFileResponse()
        if (req.hasByteRange()) {
            return GCDWebServerFileResponse(file: filePath, byteRange: req.byteRange)
        } else {
            return GCDWebServerFileResponse(file: filePath)
        }
    })