Skip to content

Commit

Permalink
feat: submit transcoding request finished (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
sirily11 authored Jul 16, 2022
1 parent 39b6cd0 commit cc3af02
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ import model
*/
struct TranscodeController: RouteCollection {
func boot(routes: RoutesBuilder) throws {
routes.post("video", "transcoding", ":id", use: submitTranscodeRequest)
routes.post("video", "transcoding", "analyzing", use: submitAnalyzingResult)
routes.post("video", "transcoding", "result" ,use: submitTranscodingResult)
routes.get("video", "transcoding", "result", ":id", use: getTranscodingJobs)
}
/**
Submit a transcoding request. This will also send video to the analyzing worker
*/
func submitTranscodeRequest(req: Request) async throws -> Response {
return Response(status: .accepted)
func submitTranscodeRequest(req: Request) async throws -> AnalyzingJob {
let id = try req.parameters.require("id", as: UUID.self)
let video = try await VideoInfo.find(id, on: req.db)
guard let video = video else {
throw Abort(.notFound, reason: "Cannot find video with id: \(id)")
}
let downloadURL = try await getDownloadURL(req: req, video: video)
let job = try await AnalyzingJob.fromVideo(req: req, videoSource: downloadURL, videoId: id.uuidString)
let encodedData = try JSONEncoder().encode(job)

video.status = .encoding
try await video.update(on: req.db)

try await req.mqtt.client.publish(to: Channels.analyzingWorker.rawValue, payload: .init(bytes: encodedData), qos: .atLeastOnce)
return job
}

/**
Expand Down Expand Up @@ -71,7 +85,7 @@ struct TranscodeController: RouteCollection {
video.cover = analyzingResult.cover
video.length = analyzingResult.length
video.quality = analyzingResult.quality
try await video.save(on: req.db)
try await video.update(on: req.db)

// create a list of transcoding jobs
let targetTranscodingJobs: [TranscodingJob] = try await analyzingResult.quality.getListTranscodingTargets().concurrentMap { res async throws in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import Foundation
import Vapor
import model
import common


struct AnalyzingRequest: Content {
/**
Expand All @@ -32,10 +34,11 @@ struct AnalyzingRequest: Content {


var fileName: String

}


struct AnalyzingJob: Codable {
struct AnalyzingJob: Content {
/**
Pre-signed url for cover upload
*/
Expand All @@ -44,6 +47,23 @@ struct AnalyzingJob: Codable {
Pre-signed url for video download
*/
var source: String


static func fromVideo(req: Request, videoSource: String, videoId: String) async throws -> AnalyzingJob {
let endpoint = Environment.get(ENVIRONMENT_S3_ENDPOINT)!
let bucket = Environment.get(ENVIRONMENT_S3_BUCKET_NAME)!

let coverURL: String = "\(endpoint)/\(bucket)/cover/\(videoId).png"
guard let url = URL(string: coverURL) else {
throw Abort(.internalServerError, reason: "Cannot construct a valid cover url: \(coverURL)")
}

guard let presigned = try? await req.s3.signURL(url: url, httpMethod: .PUT, expires: .hours(1)) else {
throw Abort(.internalServerError, reason: "Cannot construct a pre-signed valid cover url: \(coverURL)")
}

return AnalyzingJob(cover: presigned.absoluteString, source: videoSource)
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,56 @@ final class AppTests: XCTestCase {
XCTAssertEqual(res.status, .ok)
XCTAssertEqual(content.status, .failed)
})
}


func testSubmitTranscodingRequest() async throws {
let app = Application(.testing)
defer {
cleanUp(app: app)
app.shutdown()
}
try configure(app)

let video = VideoInfo(title: "a", labels: [], description: nil, cover: nil, source: "http://localhost:4566/video-trading/upload/file3.mov",
transcoding: [], status: .uploaded, statusDescription: nil, length: nil,
fileName: "upload/file3.mov", bucketName: "video-trading")

let _ = try? await app.aws.s3.createBucket(.init(bucket: "video-trading"))
let _ = try await app.aws.s3.putObject(.init(bucket: "video-trading", key: "upload/file3.mov"))

try await video.create(on: app.db)

try app.test(.POST, "video/transcoding/\(video.id!.uuidString)", afterResponse: { res in
XCTAssertEqual(res.status, .ok)
let data = try res.content.decode(AnalyzingJob.self)
XCTAssertContains(data.cover, "http://localhost:4566/video-trading/cover/\(video.id!.uuidString).png")
})

let updatedVideo = try await VideoInfo.find(video.id, on: app.db)
XCTAssertEqual(updatedVideo!.status, .encoding)
}


func testSubmitTranscodingRequestNotFound() async throws {
let app = Application(.testing)
defer {
cleanUp(app: app)
app.shutdown()
}
try configure(app)

let video = VideoInfo(title: "a", labels: [], description: nil, cover: nil, source: "http://localhost:4566/video-trading/upload/file4.mov",
transcoding: [], status: .uploaded, statusDescription: nil, length: nil,
fileName: "upload/file4.mov", bucketName: "video-trading")

let _ = try? await app.aws.s3.createBucket(.init(bucket: "video-trading"))
let _ = try await app.aws.s3.putObject(.init(bucket: "video-trading", key: "upload/file4.mov"))

try await video.create(on: app.db)

try app.test(.POST, "video/transcoding/\(UUID().uuidString)", afterResponse: { res in
XCTAssertEqual(res.status, .notFound)
})
}
}

0 comments on commit cc3af02

Please sign in to comment.