XCode 发起视频 和 收到视频通话邀请实现双语功能 中文和俄语

目录

[🚀 一键生成 Xcode Demo 工程(完整版)](#🚀 一键生成 Xcode Demo 工程(完整版))

[✅ 第一步:创建工程(用 Xcode CLI)](#✅ 第一步:创建工程(用 Xcode CLI))

[✅ 第二步:创建源码目录](#✅ 第二步:创建源码目录)

[✅ 第三步:创建核心文件](#✅ 第三步:创建核心文件)

[🔹 main.swift(入口)](#🔹 main.swift(入口))

[🔹 ViewController.swift](#🔹 ViewController.swift)

[🔹 CallViewController.swift](#🔹 CallViewController.swift)

[🔹 SpeechManager.swift](#🔹 SpeechManager.swift)

[🔹 TranslateManager.swift](#🔹 TranslateManager.swift)

[🔹 CameraManager.swift](#🔹 CameraManager.swift)

[✅ 第四步:直接生成 Xcode 工程](#✅ 第四步:直接生成 Xcode 工程)

[⚠️ 第五步(必须做)](#⚠️ 第五步(必须做))

[🎉 完成效果](#🎉 完成效果)


🚀 一键生成 Xcode Demo 工程(完整版)

✅ 第一步:创建工程(用 Xcode CLI)

复制代码
cd ~/Desktop
mkdir VideoCallDemo
cd VideoCallDemo

swift package init --type executable

👉 然后执行:

复制代码
open Package.swift

把它改成👇(关键)

复制代码
// swift-tools-version:5.9
import PackageDescription

let package = Package(
    name: "VideoCallDemo",
    platforms: [.iOS(.v15)],
    products: [
        .iOSApplication(
            name: "VideoCallDemo",
            targets: ["AppModule"],
            bundleIdentifier: "com.demo.videocall",
            teamIdentifier: "",
            displayVersion: "1.0",
            bundleVersion: "1",
            iconAssetName: "AppIcon",
            accentColorAssetName: "AccentColor"
        )
    ],
    targets: [
        .executableTarget(
            name: "AppModule",
            path: "Sources"
        )
    ]
)

✅ 第二步:创建源码目录

复制代码
rm -rf Sources/*
mkdir Sources/AppModule
cd Sources/AppModule

✅ 第三步:创建核心文件


🔹 main.swift(入口)

复制代码
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()

        return true
    }
}

🔹 ViewController.swift

复制代码
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        let callBtn = UIButton(frame: CGRect(x: 80, y: 200, width: 240, height: 50))
        callBtn.setTitle("发起视频通话", for: .normal)
        callBtn.backgroundColor = .systemBlue
        callBtn.addTarget(self, action: #selector(startCall), for: .touchUpInside)

        let receiveBtn = UIButton(frame: CGRect(x: 80, y: 300, width: 240, height: 50))
        receiveBtn.setTitle("模拟来电", for: .normal)
        receiveBtn.backgroundColor = .systemGreen
        receiveBtn.addTarget(self, action: #selector(receiveCall), for: .touchUpInside)

        view.addSubview(callBtn)
        view.addSubview(receiveBtn)
    }

    @objc func startCall() {
        present(CallViewController(), animated: true)
    }

    @objc func receiveCall() {
        let alert = UIAlertController(title: "来电", message: "是否接听?", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "接听", style: .default) { _ in
            self.present(CallViewController(), animated: true)
        })
        alert.addAction(UIAlertAction(title: "拒绝", style: .cancel))
        present(alert, animated: true)
    }
}

🔹 CallViewController.swift

复制代码
import UIKit
import AVFoundation
import Speech

class CallViewController: UIViewController {

    let cameraView = UIView()
    let subtitleLabel = UILabel()

    let speech = SpeechManager()
    let translator = TranslateManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        startSpeech()
        CameraManager().startPreview(in: cameraView)
    }

    func setupUI() {
        view.backgroundColor = .black

        cameraView.frame = view.bounds
        view.addSubview(cameraView)

        subtitleLabel.frame = CGRect(x: 20, y: view.frame.height - 200, width: view.frame.width - 40, height: 80)
        subtitleLabel.textColor = .white
        subtitleLabel.numberOfLines = 0
        view.addSubview(subtitleLabel)

        let hangup = UIButton(frame: CGRect(x: view.center.x - 30, y: view.frame.height - 80, width: 60, height: 60))
        hangup.backgroundColor = .red
        hangup.layer.cornerRadius = 30
        hangup.setTitle("挂", for: .normal)
        hangup.addTarget(self, action: #selector(close), for: .touchUpInside)
        view.addSubview(hangup)
    }

    @objc func close() {
        dismiss(animated: true)
    }

    func startSpeech() {
        speech.start { text in
            DispatchQueue.main.async {
                self.subtitleLabel.text = text
            }

            self.translator.translateToRussian(text: text) { ru in
                DispatchQueue.main.async {
                    self.subtitleLabel.text = "\(text)\n\(ru)"
                }
            }
        }
    }
}

🔹 SpeechManager.swift

复制代码
import Speech
import AVFoundation

class SpeechManager {

    let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "zh-CN"))
    let engine = AVAudioEngine()

    func start(callback: @escaping (String)->Void) {

        let request = SFSpeechAudioBufferRecognitionRequest()

        recognizer?.recognitionTask(with: request) { result, _ in
            if let text = result?.bestTranscription.formattedString {
                callback(text)
            }
        }

        let node = engine.inputNode
        node.installTap(onBus: 0, bufferSize: 1024, format: node.outputFormat(forBus: 0)) {
            buffer, _ in
            request.append(buffer)
        }

        try? engine.start()
    }
}

🔹 TranslateManager.swift

复制代码
class TranslateManager {

    func translateToRussian(text: String, completion: @escaping (String)->Void) {
        DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
            completion("(俄语)\(text)")
        }
    }
}

🔹 CameraManager.swift

复制代码
import AVFoundation
import UIKit

class CameraManager {

    func startPreview(in view: UIView) {

        let session = AVCaptureSession()

        guard let device = AVCaptureDevice.default(for: .video),
              let input = try? AVCaptureDeviceInput(device: device)
        else { return }

        session.addInput(input)

        let preview = AVCaptureVideoPreviewLayer(session: session)
        preview.frame = view.bounds
        preview.videoGravity = .resizeAspectFill

        view.layer.addSublayer(preview)

        session.startRunning()
    }
}

✅ 第四步:直接生成 Xcode 工程

复制代码
swift package generate-xcodeproj
open VideoCallDemo.xcodeproj

⚠️ 第五步(必须做)

在 Xcode → Info.plist 添加:

复制代码
Privacy - Camera Usage Description
Privacy - Microphone Usage Description
Privacy - Speech Recognition Usage Description

🎉 完成效果

运行后你会得到:

  • ✔ 视频界面(摄像头)

  • ✔ 中文语音识别

  • ✔ 中 → 俄字幕

  • ✔ 发起 / 接听流程

相关推荐
UXbot6 小时前
2026年AI全链路产品开发工具对比:5款从创意到上线一站式平台深度解析
前端·ui·kotlin·软件构建·swift·原型模式
报错小能手9 小时前
ios开发方向——swift并发进阶核心 @MainActor 与 DispatchQueue.main 解析
开发语言·ios·swift
报错小能手2 天前
ios开发方向——swift并发进阶核心 async/await 详解
开发语言·ios·swift
用户79457223954132 天前
【Lottie】让设计稿上的动效直接"活"在 App 里
swiftui·swift
Mr_Tony4 天前
Swift 中的 Combine 框架完整指南(含示例代码 + 实战)
开发语言·swift
用户79457223954134 天前
【SnapKit】优雅的 Swift Auto Layout DSL 库
swiftui·swift
报错小能手4 天前
ios开发方向——swift内存基础
开发语言·ios·swift
东坡肘子4 天前
苹果的罕见妥协:当高危漏洞遇上“拒升”潮 -- 肘子的 Swift 周报 #130
人工智能·swiftui·swift
ˇasushiro5 天前
终端工具配置
开发语言·ios·swift