You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中使用Ktor Client分片发送大视频至服务器的实现方案

大视频分片上传实现方案(基于Ktor Client)

核心思路

将大视频文件按固定大小分割为多个分片,通过Ktor Client依次向服务器发送每个分片;所有分片上传完成后,通知服务器合并分片为完整文件。同时加入可靠性机制(重试、断点续传、校验)确保上传成功率。

具体实现步骤

1. 本地文件分片处理

先确定分片大小(建议10MB~50MB,平衡请求次数和单请求大小),然后循环读取文件的每个分片内容:

import java.io.File
import kotlin.math.min

val videoFile = File("/path/to/your-large-video.mp4")
val chunkSize = 10 * 1024 * 1024 // 10MB 分片大小
val totalChunks = (videoFile.length() + chunkSize - 1) / chunkSize // 向上取整计算总分片数

// 遍历每个分片
for (chunkIndex in 0 until totalChunks.toInt()) {
    val startPos = chunkIndex * chunkSize
    val endPos = min(startPos + chunkSize, videoFile.length())
    val chunkBytes = videoFile.readBytes(startPos.toInt(), (endPos - startPos).toInt())
    
    // 调用上传函数发送当前分片
    uploadChunkWithRetry(chunkBytes, videoFile.name, chunkIndex, totalChunks)
}

// 所有分片上传完成后请求合并
requestMerge(videoFile.name, totalChunks)

2. Ktor Client分片上传实现

配置Ktor Client,每个分片以二进制流形式发送,通过请求头传递分片元数据(文件名、索引、总分片数等):

import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.timeout.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json

// 初始化Ktor Client,添加超时和JSON解析支持
val ktorClient = HttpClient(OkHttp) {
    install(ContentNegotiation) {
        json(Json { ignoreUnknownKeys = true })
    }
    install(HttpTimeout) {
        requestTimeoutMillis = 30 * 1000 // 请求超时30秒
        connectTimeoutMillis = 10 * 1000 // 连接超时10秒
    }
}

// 单分片上传函数
suspend fun uploadChunk(chunkBytes: ByteArray, fileName: String, chunkIndex: Int, totalChunks: Long) {
    val response = ktorClient.post("https://your-server-domain/upload/chunk") {
        contentType(ContentType.Application.OctetStream)
        setBody(chunkBytes)
        headers {
            append("X-File-Name", fileName)
            append("X-Chunk-Index", chunkIndex.toString())
            append("X-Total-Chunks", totalChunks.toString())
            // 可选:添加文件全局哈希,用于服务器最终校验完整性
            append("X-File-Hash", calculateFileHash(videoFile))
        }
    }

    // 校验上传是否成功
    if (!response.status.isSuccess()) {
        throw RuntimeException("分片 ${chunkIndex+1}/${totalChunks} 上传失败,状态码:${response.status.value}")
    }
}

// 请求服务器合并分片
suspend fun requestMerge(fileName: String, totalChunks: Long) {
    val response = ktorClient.post("https://your-server-domain/upload/merge") {
        contentType(ContentType.Application.Json)
        setBody(mapOf(
            "fileName" to fileName,
            "totalChunks" to totalChunks,
            "fileHash" to calculateFileHash(videoFile)
        ))
    }

    if (!response.status.isSuccess()) {
        throw RuntimeException("合并请求失败,状态码:${response.status.value}")
    }
}

// 辅助函数:计算文件哈希(示例用MD5)
fun calculateFileHash(file: File): String {
    return file.inputStream().use { input ->
        java.security.MessageDigest.getInstance("MD5").digest(input.readBytes())
            .joinToString("") { "%02x".format(it) }
    }
}

3. 可靠性增强机制

  • 重试逻辑:对上传失败的分片自动重试,可通过自定义循环实现:
    suspend fun uploadChunkWithRetry(chunkBytes: ByteArray, fileName: String, chunkIndex: Int, totalChunks: Long, maxRetries: Int = 3) {
        var retryCount = 0
        while (retryCount < maxRetries) {
            try {
                uploadChunk(chunkBytes, fileName, chunkIndex, totalChunks)
                return
            } catch (e: Exception) {
                retryCount++
                if (retryCount == maxRetries) throw e
                // 重试前按次数递增延迟
                kotlinx.coroutines.delay(1000 * retryCount)
            }
        }
    }
    
  • 断点续传:本地记录已成功上传的分片索引(比如存在SharedPreferences或本地文件),下次上传时跳过已完成的分片。
  • 分片校验:服务器返回分片的哈希值,客户端比对本地计算的分片哈希,确保传输完整性。

优化建议

  • 若业务允许,可改为并发上传(控制并发数,避免服务器压力过大),但需确保服务器支持乱序接收分片。
  • 添加上传进度监听:通过Ktor的ProgressListener跟踪每个分片的上传进度,更新UI或日志。
  • 分片大小可根据网络动态调整:比如弱网环境下减小分片大小,提升成功率。

内容的提问来源于stack exchange,提问作者Saeed Noshadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:40:28