オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
POSTED BY
2025-07-08
2025-07-08

オープンソースリップシンクエンジンSadTalkerをDebianで動かす
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
前回まででAPI待ち受けのサーバー準備は整ったので、次はSwift UI iOSアプリからあらかじめ用意した画像とWAVデータを投げて、生成された動画を受け取り表示する。
1、しゃべらせる顔の画像「face_sample.png」を用意して、Assetsにドロップして登録する。
2、しゃべらせる音声データ「voice_sample.wav」を用意して、プロジェクト直下(ContentView.swiftなどと同じ場所)へドロップして登録する。「Copy items if needed」「Add to targets」を忘れずに。
3、以下のContentView.swiftコードを書く。
| Swift | ContentView.swift | GitHub Source |
import SwiftUI
import AVKit
struct ContentView: View {
@State private var videoURL: URL?
@State private var isLoading = false
var body: some View {
VStack {
if let videoURL = videoURL {
VideoPlayer(player: AVPlayer(url: videoURL))
.frame(height: 300)
}
Button("アップロードして動画生成") {
Task {
await uploadAndFetchVideo()
}
}
.disabled(isLoading)
.padding()
if isLoading {
ProgressView("生成中...")
}
}
}
func uploadAndFetchVideo() async {
guard let image = UIImage(named: "face_sample"),
let imageData = image.jpegData(compressionQuality: 0.8),
let audioURL = Bundle.main.url(forResource: "voice_sample", withExtension: "wav")
else {
print("画像または音声が見つかりません")
return
}
isLoading = true
defer { isLoading = false }
let boundary = "Boundary-\(UUID().uuidString)"
var request = URLRequest(url: URL(string: "https://voicetech.jorudan.co.jp/sadtalker_api/generate")!)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
var body = Data()
// 画像パート
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"source_image\"; filename=\"image.jpg\"\r\n")
body.append("Content-Type: image/jpeg\r\n\r\n")
body.append(imageData)
body.append("\r\n")
// 音声パート
if let audioData = try? Data(contentsOf: audioURL) {
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"driven_audio\"; filename=\"audio.wav\"\r\n")
body.append("Content-Type: audio/wav\r\n\r\n")
body.append(audioData)
body.append("\r\n")
}
body.append("--\(boundary)--\r\n")
do {
let (data, response) = try await URLSession.shared.upload(for: request, from: body)
guard let httpResp = response as? HTTPURLResponse, httpResp.statusCode == 200 else {
print("エラー: サーバー応答 \(response)")
return
}
// 一時ファイルに保存
let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent("result.mp4")
try data.write(to: tempURL)
videoURL = tempURL
} catch {
print("アップロードエラー: \(error)")
}
}
}
// ヘルパー:Data拡張
extension Data {
mutating func append(_ string: String) {
if let data = string.data(using: .utf8) {
append(data)
}
}
}
これで実行すると、かなり待つものの生成されたしゃべる静止画をアプリで再生できる。サーバー側は成功していれば以下のようなログが出ているはずだ。
using safetensor as default landmark Det:: 100%|| 1/1 [19.13it/s] 3DMM Extraction In Video:: 100%|| 1/1 [66.61it/s] mel:: 100%|| 79/79 [44898.38it/s] audio2exp:: 100%|| 8/8 [293.43it/s] Face Renderer:: 100%|| 40/40 [2.97it/s] The generated video is named /home/hogeuser/SadTalker/working_dir/20250708_212639/2025_07_08_21.26.39/input_input.mp4 INFO: xxx.yy.zzz.aa:0 - "POST /sadtalker_api/generate HTTP/1.1" 200 OK
あとはアプリ側は実際にマイクで録音したデータやカメラで撮った自写真などをそのまま送れるようにすると完成が近い。疲れたので次回以降に。
Android
iPhone/iPad
Flutter
MacOS
Windows
Debian
Ubuntu
CentOS
FreeBSD
RaspberryPI
HTML/CSS
C/C++
PHP
Java
JavaScript
Node.js
Swift
Python
MatLab
Amazon/AWS
CORESERVER
Google
仮想通貨
LINE
OpenAI/ChatGPT
IBM Watson
Microsoft Azure
Xcode
VMware
MySQL
PostgreSQL
Redis
Groonga
Git/GitHub
Apache
nginx
Postfix
SendGrid
Hackintosh
Hardware
Fate/Grand Order
ウマ娘
将棋
ドラレコ
※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!ご連絡は以下アドレスまでお願いします★
【キーワード検索】
【最近の記事】【全部の記事】
LetsEncrypt/certbotの証明書自動更新がエラーになる場合Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【Let's Encrypt】Failed authorization procedure 503の対処法
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
ファイアウォール内部のWindows11 PCにmacOS Sequoiaからリモートデスクトップする
【人気の記事】【全部の記事】
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法進研ゼミチャレンジタッチをAndroid端末化する
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
C言語用最新NKFライブラリlibnkf-2.1.5を作成して文字コード変換
Windows11のコマンドプロンプトでテキストをコピーする
GitLabにHTTPS経由でリポジトリをクローン&読み書きを行う
タスクスケジューラで変更を適用できません。ユーザーアカウントが不明であるか、パスワードが正しくないか、またはユーザーアカウントにタスクを変更する許可がありません。と出た
Googleファミリーリンクで子供の端末の現在地がエラーで取得できない場合
【Apache】サーバーに同時接続可能なクライアント数を調整する
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
【カテゴリーリンク】
Android
iPhone/iPad
Flutter
MacOS
Windows
Debian
Ubuntu
CentOS
FreeBSD
RaspberryPI
HTML/CSS
C/C++
PHP
Java
JavaScript
Node.js
Swift
Python
MatLab
Amazon/AWS
CORESERVER
Google
仮想通貨
LINE
OpenAI/ChatGPT
IBM Watson
Microsoft Azure
Xcode
VMware
MySQL
PostgreSQL
Redis
Groonga
Git/GitHub
Apache
nginx
Postfix
SendGrid
Hackintosh
Hardware
Fate/Grand Order
ウマ娘
将棋
ドラレコ