AndServer icon indicating copy to clipboard operation
AndServer copied to clipboard

StorageWebsite加载大文件

Open zk0301 opened this issue 7 years ago • 9 comments

服务端使用storagewebsite, 客户端用android videoview播放 http://xxxxxxxxx:8080/mnt/sdcard/www/video/test.mp4

test.mp4,大小50M的时候可以播放。 换一个1G大的文件,videoview报“无法播放此视频”。

zk0301 avatar Apr 14 '17 05:04 zk0301

这个视频直接播放呢,不要通过AndServer,是不是这个视频本身有问题呢?

yanzhenjie avatar Apr 14 '17 10:04 yanzhenjie

@yanzhenjie 视频本身没有问题哦。 直接播放sdcard的话没有问题。我就是想通过AndServer播放啊哈哈。楼主有空帮看看啊。

zk0301 avatar Apr 17 '17 09:04 zk0301

好的,改天我研究下。

yanzhenjie avatar Apr 17 '17 12:04 yanzhenjie

好的,改天我研究下。

楼主,为嘛通过AndServer下发视频在iOS系统上无法播放,安卓上是没问题的.

Jerryshen170918 avatar Nov 08 '18 01:11 Jerryshen170918

服务端使用storagewebsite, 客户端用android videoview播放 http://xxxxxxxxx:8080/mnt/sdcard/www/video/test.mp4

test.mp4,大小50M的时候可以播放。 换一个1G大的文件,videoview报“无法播放此视频”。

视频能在iOS上播放吗

Jerryshen170918 avatar Nov 08 '18 01:11 Jerryshen170918

服务端使用storagewebsite, 客户端用android videoview播放 http://xxxxxxxxx:8080/mnt/sdcard/www/video/test.mp4 test.mp4,大小50M的时候可以播放。 换一个1G大的文件,videoview报“无法播放此视频”。

视频能在iOS上播放吗

我也语到了,是不是和Range有关?

chenweitracy avatar Jun 22 '19 03:06 chenweitracy

可以试试nanohttpd

ag2s20150909 avatar Jan 12 '20 12:01 ag2s20150909

我用nanohttpd解决了,核心代码如下

    private fun respond(headers: Map<String, String>, file: File): Response {
        var res: Response?
        val inputStream = FileInputStream(file)
        var mimeType = H5FileUtil.getMimeType(file)
        if (mimeType.isNullOrBlank()) {
            mimeType = "application/octet-stream"
        }
        var startFrom: Long = 0
        var endAt: Long = -1
        var range = headers["range"]
        if (range != null) {
            if (range.startsWith("bytes=")) {
                range = range.substring("bytes=".length)
                val minus = range.indexOf('-')
                try {
                    if (minus > 0) {
                        startFrom = range.substring(0, minus).toLong()
                        endAt = range.substring(minus + 1).toLong()
                    }
                } catch (ignored: NumberFormatException) {
                }
            }
        }

        val fileLen: Long = inputStream.available().toLong()
        if (range != null && startFrom >= 0) {
            if (startFrom >= fileLen) {
                res = createResponse(Response.Status.RANGE_NOT_SATISFIABLE, MIME_PLAINTEXT, "")
                res?.addHeader("Content-Range", "bytes 0-0/$fileLen")
            } else {
                if (endAt < 0) {
                    endAt = fileLen - 1
                }
                inputStream.skip(startFrom)
                res = createResponse(Response.Status.PARTIAL_CONTENT, mimeType, inputStream)
                res?.addHeader("Content-Range", "bytes $startFrom-$endAt/$fileLen")
            }
        } else {
            res = createResponse(Response.Status.OK, mimeType, inputStream, fileLen)
        }
        return res?.let {
            it
        } ?: notFound()
    }

    private fun createResponse(
        status: Response.Status,
        mimeType: String,
        message: InputStream,
        total: Long = -1
    ): Response? {
        val res = newFixedLengthResponse(status, mimeType, message, total)
        res.addHeader("Accept-Ranges", "bytes")
        res.addHeader("Access-Control-Allow-Origin", "*")
        return res
    }

    private fun createResponse(
        status: Response.Status,
        mimeType: String,
        message: String
    ): Response? {
        val res = newFixedLengthResponse(status, mimeType, message)
        res.addHeader("Accept-Ranges", "bytes")
        res.addHeader("Access-Control-Allow-Origin", "*")
        return res
    }

snice avatar Sep 28 '20 03:09 snice