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

如何使用Akka HTTP构造调用Facebook API的form-data请求?

用Akka HTTP实现Facebook视频分片上传的Form-Data请求

嘿,我来帮你搞定这个需求!先对照你给出的curl示例和FBSingleChunkUpload case class,一步步实现对应的form-data POST请求:

第一步:补全你的Case Class

首先把case class的字段和curl里的参数一一对应上,确保所有必要字段都包含:

case class FBSingleChunkUpload(
  accessToken: String,       // 对应curl里的access_token
  sessionId: String,         // 对应upload_session_id
  startOffset: Long,         // 对应start_offset
  videoChunk: java.io.File   // 对应video_file_chunk的本地文件,也可以换成流式Source
)

第二步:构建Akka HTTP的Form-Data实体

Akka HTTP通过Multipart.FormData来处理form-data类型的请求,我们需要把每个字段转换成对应的BodyPart:

先导入必要的包

确保你的项目依赖里已经包含Akka HTTP,然后导入这些核心包:

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.scaladsl.FileIO
import scala.concurrent.Future

编写FormData构建函数

把case class的内容转换成符合要求的form-data结构:

def buildFormData(uploadReq: FBSingleChunkUpload): Multipart.FormData = {
  // 普通文本字段部分
  val accessTokenPart = Multipart.FormData.BodyPart(
    "access_token",
    HttpEntity(ContentTypes.`text/plain(UTF-8)`, uploadReq.accessToken)
  )
  
  // upload_phase是固定值transfer
  val uploadPhasePart = Multipart.FormData.BodyPart(
    "upload_phase",
    HttpEntity(ContentTypes.`text/plain(UTF-8)`, "transfer")
  )
  
  val startOffsetPart = Multipart.FormData.BodyPart(
    "start_offset",
    HttpEntity(ContentTypes.`text/plain(UTF-8)`, uploadReq.startOffset.toString)
  )
  
  val sessionIdPart = Multipart.FormData.BodyPart(
    "upload_session_id",
    HttpEntity(ContentTypes.`text/plain(UTF-8)`, uploadReq.sessionId)
  )
  
  // 文件块部分:用FileIO读取本地文件,自动处理流式上传
  val videoChunkPart = Multipart.FormData.BodyPart.fromFile(
    "video_file_chunk",
    ContentType(MediaTypes.`video/mp4`),
    uploadReq.videoChunk
  )
  
  // 把所有BodyPart组合成完整的FormData
  Multipart.FormData(accessTokenPart, uploadPhasePart, startOffsetPart, sessionIdPart, videoChunkPart)
}

第三步:发送POST请求并处理响应

编写发送请求的函数,处理Akka HTTP的异步响应:

def sendFacebookUploadRequest(uploadReq: FBSingleChunkUpload)(implicit system: ActorSystem): Future[HttpResponse] = {
  import system.dispatcher
  
  val formData = buildFormData(uploadReq)
  // 替换成你实际的Facebook API端点
  val apiUri = Uri("https://graph-video.facebook.com/v2.3/1533641336884006/videos")
  
  val httpRequest = HttpRequest(
    method = HttpMethods.POST,
    uri = apiUri,
    entity = formData.toEntity(HttpCharsets.`UTF-8`)
  )
  
  // 发送单次请求
  Http().singleRequest(httpRequest)
}

使用示例

这里是一个简单的调用示例,上传本地的chunk文件:

// 初始化ActorSystem(Akka HTTP的核心依赖)
implicit val system: ActorSystem = ActorSystem("FacebookVideoUploader")

val chunkFile = new java.io.File("chunk1.mp4")
val uploadRequest = FBSingleChunkUpload(
  accessToken = "XXXXXXX",
  sessionId = "1564747013773438",
  startOffset = 0,
  videoChunk = chunkFile
)

// 发送请求并处理结果
sendFacebookUploadRequest(uploadRequest).onComplete {
  case scala.util.Success(response) =>
    println(s"上传请求响应状态: ${response.status}")
    // 可以进一步读取响应体内容
    response.entity.dataBytes.runForeach(bs => println(bs.utf8String))
  case scala.util.Failure(ex) =>
    println(s"上传失败,错误信息: ${ex.getMessage}")
}

额外注意事项

  • 如果你的视频块不是本地文件,而是流式数据(比如从网络读取的字节流),可以用自定义的Source[ByteString, _]来构建文件BodyPart:
    val chunkSource: akka.stream.scaladsl.Source[ByteString, _] = // 你的流式数据源
    val videoChunkPart = Multipart.FormData.BodyPart(
      "video_file_chunk",
      HttpEntity(ContentType(MediaTypes.`video/mp4`), chunkSource),
      Map("filename" -> "chunk1.mp4") // 记得指定文件名
    )
    
  • 生产环境中不要用Await等待Future结果,建议用回调或者for-comprehension处理异步流程
  • 你用的Facebook API v2.3版本比较老旧,建议尽量升级到较新的版本以获得更好的兼容性和功能

内容的提问来源于stack exchange,提问作者Alex Fruzenshtein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:52:30