Ниже у меня есть код для объединения видеоклипов в одно видео. У меня нет большого опыта работы с AVFoundation, поэтому я не уверен, как заменить устаревший код обновленными методами, не вызывая ошибки:
Тип «CameraViewModel» не соответствует протоколу «AVCaptureFileOutputRecordingDelegate».
Этот код отлично работает для iOS 15, но в iOS 16 он устарел. В первом фрагменте кода ниже находится исходный устаревший код (устаревший код, в частности, в функции mergeVideos). Во втором фрагменте кода я пытаюсь обновить устаревший код правильным, но при этом получаю ошибку, указанную выше.
В своем коде я изменил устаревший asset.duration на асинхронный asset.load(.duration)
Я также изменил asset.tracks(withMediaType: .audio)[0] в асинхронный asset.loadTracks(withMediaType: .audio)
import SwiftUI
import SwiftUI
import AVFoundation
class CameraViewModel: NSObject, ObservableObject, AVCaptureFileOutputRecordingDelegate{
@Published var session = AVCaptureSession()
@Published var alert = false
@Published var output = AVCaptureMovieFileOutput()
@Published var preview : AVCaptureVideoPreviewLayer!
@Published var isRecording: Bool = false
@Published var recordedURLs: = []
@Published var previewURL: URL?
@ ... deprecated
Методы Swift AVFoundation устарели. ⇐ IOS
Программируем под IOS
1760386264
Anonymous
Ниже у меня есть код для объединения видеоклипов в одно видео. У меня нет большого опыта работы с AVFoundation, поэтому я не уверен, как заменить устаревший код обновленными методами, не вызывая ошибки:
Тип «CameraViewModel» не соответствует протоколу «AVCaptureFileOutputRecordingDelegate».
Этот код отлично работает для iOS 15, но в iOS 16 он устарел. В первом фрагменте кода ниже находится исходный устаревший код (устаревший код, в частности, в функции mergeVideos). Во втором фрагменте кода я пытаюсь обновить устаревший код правильным, но при этом получаю ошибку, указанную выше.
В своем коде я изменил устаревший [b]asset.duration[/b] на асинхронный [b]asset.load(.duration)[/b]
Я также изменил [b]asset.tracks(withMediaType: .audio)[0][/b] в асинхронный [b]asset.loadTracks(withMediaType: .audio)[/b]
import SwiftUI
import SwiftUI
import AVFoundation
class CameraViewModel: NSObject, ObservableObject, AVCaptureFileOutputRecordingDelegate{
@Published var session = AVCaptureSession()
@Published var alert = false
@Published var output = AVCaptureMovieFileOutput()
@Published var preview : AVCaptureVideoPreviewLayer!
@Published var isRecording: Bool = false
@Published var recordedURLs: [URL] = []
@Published var previewURL: URL?
@Published var showPreview: Bool = false
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if let error = error {
print(error.localizedDescription)
return
}
self.recordedURLs.append(outputFileURL)
if self.recordedURLs.count == 1{
self.previewURL = outputFileURL
return
}
let assets = recordedURLs.compactMap { url -> AVURLAsset in
return AVURLAsset(url: url)
}
self.previewURL = nil
mergeVideos(assets: assets) { exporter in // ADD AWAIT HERE
exporter.exportAsynchronously {
if exporter.status == .failed{
print(exporter.error!)
}
else{
if let finalURL = exporter.outputURL{
print(finalURL)
DispatchQueue.main.async {
self.previewURL = finalURL
}
}
}
}
}
}
func mergeVideos(assets: [AVURLAsset],completion: @escaping (_ exporter: AVAssetExportSession)->()){
let compostion = AVMutableComposition()
var lastTime: CMTime = .zero
guard let videoTrack = compostion.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else{return}
guard let audioTrack = compostion.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else{return}
for asset in assets {
// Linking Audio and Video
do{
try videoTrack.insertTimeRange(CMTimeRange(start: .zero, duration: asset.duration), of: asset.tracks(withMediaType: .video)[0], at: lastTime)
// Safe Check if Video has Audio
if !asset.tracks(withMediaType: .audio).isEmpty{
try audioTrack.insertTimeRange(CMTimeRange(start: .zero, duration: asset.duration), of: asset.tracks(withMediaType: .audio)[0], at: lastTime)
}
}
catch{
// HANDLE ERROR
print(error.localizedDescription)
}
// Updating Last Time
lastTime = CMTimeAdd(lastTime, asset.duration)
}
//more code
}
}
import SwiftUI
import SwiftUI
import AVFoundation
class CameraViewModel: NSObject, ObservableObject, AVCaptureFileOutputRecordingDelegate{
@Published var session = AVCaptureSession()
@Published var alert = false
@Published var output = AVCaptureMovieFileOutput()
@Published var preview : AVCaptureVideoPreviewLayer!
@Published var isRecording: Bool = false
@Published var recordedURLs: [URL] = []
@Published var previewURL: URL?
@Published var showPreview: Bool = false
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) async { //made func async
if let error = error {
print(error.localizedDescription)
return
}
self.recordedURLs.append(outputFileURL)
if self.recordedURLs.count == 1{
self.previewURL = outputFileURL
return
}
let assets = recordedURLs.compactMap { url -> AVURLAsset in
return AVURLAsset(url: url)
}
self.previewURL = nil
await mergeVideos(assets: assets) { exporter in // ADD AWAIT HERE
exporter.exportAsynchronously {
if exporter.status == .failed{
print(exporter.error!)
}
else{
if let finalURL = exporter.outputURL{
print(finalURL)
DispatchQueue.main.async {
self.previewURL = finalURL
}
}
}
}
}
}
func mergeVideos(assets: [AVURLAsset],completion: @escaping (_ exporter: AVAssetExportSession)->()) async {
let compostion = AVMutableComposition()
var lastTime: CMTime = .zero
guard let videoTrack = compostion.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else{return}
guard let audioTrack = compostion.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else{return}
for asset in assets {
do {
//Changes
try await videoTrack.insertTimeRange(CMTimeRange(start: .zero, duration: asset.load(.duration)), of: asset.loadTracks(withMediaType: .video)[0], at: lastTime)
if try await !asset.loadTracks(withMediaType: .audio).isEmpty {
try await audioTrack.insertTimeRange(CMTimeRange(start: .zero, duration: asset.load(.duration)), of: asset.loadTracks(withMediaType: .audio)[0], at: lastTime)
}
}
catch {
print(error.localizedDescription)
}
do {
lastTime = try await CMTimeAdd(lastTime, asset.load(.duration))
} catch {
print(error.localizedDescription)
}
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/77596332/swift-avfoundation-methods-have-been-deprecated[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия