How can I use ktor to serve remote video instead of Nanohttpd?

91 Views Asked by At

I want to use ktor to serve videos for casting to tv but video is seekable when I test in browser but when i stream video to tv via connectsdk , it streams video but not allowing to seek. WHats the problem in ktor that does not allow seek to tv, while in nanohttpd with same headers it work perfect.

Code for server


object SimpleKtorServer {
    private var ktorServer: CIOApplicationEngine? = null

    fun start() {
        if (ktorServer != null) {
            ktorServer?.stop(0, 250)
            ktorServer = null
        }
        val environment = applicationEngineEnvironment {
            module {
                install(PartialContent)
                install(AutoHeadResponse)
                VideoApplicationModule()
            }
            connector {
                port = selectedPort
                host = Utils.getWifiApIpAddress()!!
            }
        }


        ktorServer = embeddedServer(CIO, environment) {
            connectionIdleTimeoutSeconds = 10
        }
        try {
            ktorServer?.start(false)
        } catch (ex: Exception) {
            Log.i("MyKtorServer", "AddressInUseException")
        }
    }
}

VideoApplicationModule

internal fun Application.VideoApplicationModule() {
    routing {
        get(videoUrl) {
            val videoId = getCastPlayList()[0].uri


            val httpURLConnection = URL(videoId).openConnection() as HttpURLConnection
            httpURLConnection.connect()
            BrowserActivity.contentLength = httpURLConnection.contentLength


            call.response.header("Access-Control-Allow-Origin", "*")
            call.response.header(
                "contentFeatures.dlna.org",
                "DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000"
            )
            call.response.header("TransferMode.DLNA.ORG", "Streaming")
            call.response.header("RealTimeInfo.DLNA.ORG", "DLNA.ORG_TLAG=*")
            call.respond(HttpStatusCode.OK, StreamCastContent(videoId))
        }
    }
}

class StreamCastContent(private val url: String) :
    OutgoingContent.ReadChannelContent() {

    override val contentType = ContentType.Video.MP4
    override fun readFrom(): ByteReadChannel {
        return getYTRemote(url, 0)!!.toByteReadChannel()
    }

    override fun readFrom(range: LongRange): ByteReadChannel {
        return getYTRemote(url, range.first)!!.toByteReadChannel()
    }

    override val contentLength = BrowserActivity.contentLength.toLong()

}

private fun getYTRemote(url: String, offset: Long): InputStream? {
    try {
        val cn = URL(url).openConnection()
        cn.setRequestProperty("Range", "bytes=$offset-")
        cn.connect()
        return cn.getInputStream()
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return null
}

I tried removing partial content and manually handling range requests but still could not be able to seek on tv. TV is samsung

0

There are 0 best solutions below