Hi,
Im using UIDocumentPicker to import an audio from my Files,
I’m getting a URL which I upload it to the Firebase Storage.
How do I trim this audio URL to 30 seconds, and get a new URL to be uploaded to the Storage?
Thank you.
Hi,
Im using UIDocumentPicker to import an audio from my Files,
I’m getting a URL which I upload it to the Firebase Storage.
How do I trim this audio URL to 30 seconds, and get a new URL to be uploaded to the Storage?
Thank you.
This code assume that you have an audio.m4a file imported in your XCode project, change the url as needed.
import UIKit
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var startTimeHoursTextfield: UITextField!
@IBOutlet weak var startTimeMinutesTextField: UITextField!
@IBOutlet weak var startTimeSecondsTextField: UITextField!
@IBOutlet weak var finalTimeHoursTextField: UITextField!
@IBOutlet weak var finalTimeMinutesTextField: UITextField!
@IBOutlet weak var finalSecondsTimeTextField: UITextField!
var asset : AVURLAsset!
let outputFileName = "output"
@IBAction func trimAudioAction(_ sender: Any) {
var startTime : Float?
var finalTime : Float?
let startTimeHoursText = startTimeHoursTextfield.text ?? "00"
let startTimeMinutesText = startTimeMinutesTextField.text ?? "00"
let startTimeSecondsText = startTimeSecondsTextField.text ?? "00"
let finalTimeHoursText = finalTimeHoursTextField.text ?? "00"
let finalTimeMinutesText = finalTimeMinutesTextField.text ?? "00"
let finalTimeSecondsText = finalSecondsTimeTextField.text ?? "00"
let startTimeHours = Float(startTimeHoursText)
let startTimeMinutes = Float(startTimeMinutesText)
let startTimeSeconds = Float(startTimeSecondsText)
let finalTimeHours = Float(finalTimeHoursText)
let finalTimeMinutes = Float(finalTimeMinutesText)
let finalTimeSeconds = Float(finalTimeSecondsText)
if let startTimeHours = startTimeHours{
startTime = startTimeHours * 60.0
}
if let startTimeMinutes = startTimeMinutes{
startTime = (startTime ?? 0) * 60.0 + startTimeMinutes * 60.0
}
if let startTimeSeconds = startTimeSeconds{
startTime = (startTime ?? 0) + startTimeSeconds
}
if let finalTimeHours = finalTimeHours{
finalTime = (finalTimeHours * 60.0)
}
if let finalTimeMinutes = finalTimeMinutes{
finalTime = (finalTime ?? 0) * 60.0 + finalTimeMinutes * 60.0
}
if let finalTimeSeconds = finalTimeSeconds{
finalTime = (finalTime ?? 0) + finalTimeSeconds
}
let length = Float(asset.duration.value) / Float(asset.duration.timescale)
print("video length: \(length) seconds")
let fileManager = FileManager.default
guard let documentDirectory = try? fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else { return }
var outputURL = documentDirectory.appendingPathComponent("output")
do {
try fileManager.createDirectory(at: outputURL, withIntermediateDirectories: true, attributes: nil)
outputURL = outputURL.appendingPathComponent("\(outputFileName).m4a")
}catch let error {
print(error)
}
//Remove previous existing file
_ = try? fileManager.removeItem(at: outputURL)
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {return}
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.m4a
let start = startTime
let end = finalTime
let startTimeRange = CMTime(seconds: Double(start ?? 0), preferredTimescale: 1000)
let endTimeRange = CMTime(seconds: Double(end ?? length), preferredTimescale: 1000)
let timeRange = CMTimeRange(start: startTimeRange, end: endTimeRange)
exportSession.timeRange = timeRange
exportSession.exportAsynchronously{
switch exportSession.status {
case .completed:
print("exported at \(outputURL)")
case .failed:
print("failed \(String(describing: exportSession.error))")
case .cancelled:
print("cancelled \(String(describing: exportSession.error))")
default:
break
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
guard let path = Bundle.main.path(forResource: "audio", ofType: "m4a") else {
fatalError("Can not get path")
}
let url = URL(fileURLWithPath: path)
asset = AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey : true])
}
}
You need to download the file from the original url to the device first, trim the file to 30 seconds and upload it to Firebase Storage and finally get the url from Firebase Storage.
Thank you for answering,
It worked for me to convert the audio file, and then getting a new URL,
Is there a way to trim the audio file in this code?
This code assume that you have an audio.m4a file imported in your XCode project, change the url as needed.
import UIKit
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var startTimeHoursTextfield: UITextField!
@IBOutlet weak var startTimeMinutesTextField: UITextField!
@IBOutlet weak var startTimeSecondsTextField: UITextField!
@IBOutlet weak var finalTimeHoursTextField: UITextField!
@IBOutlet weak var finalTimeMinutesTextField: UITextField!
@IBOutlet weak var finalSecondsTimeTextField: UITextField!
var asset : AVURLAsset!
let outputFileName = "output"
@IBAction func trimAudioAction(_ sender: Any) {
var startTime : Float?
var finalTime : Float?
let startTimeHoursText = startTimeHoursTextfield.text ?? "00"
let startTimeMinutesText = startTimeMinutesTextField.text ?? "00"
let startTimeSecondsText = startTimeSecondsTextField.text ?? "00"
let finalTimeHoursText = finalTimeHoursTextField.text ?? "00"
let finalTimeMinutesText = finalTimeMinutesTextField.text ?? "00"
let finalTimeSecondsText = finalSecondsTimeTextField.text ?? "00"
let startTimeHours = Float(startTimeHoursText)
let startTimeMinutes = Float(startTimeMinutesText)
let startTimeSeconds = Float(startTimeSecondsText)
let finalTimeHours = Float(finalTimeHoursText)
let finalTimeMinutes = Float(finalTimeMinutesText)
let finalTimeSeconds = Float(finalTimeSecondsText)
if let startTimeHours = startTimeHours{
startTime = startTimeHours * 60.0
}
if let startTimeMinutes = startTimeMinutes{
startTime = (startTime ?? 0) * 60.0 + startTimeMinutes * 60.0
}
if let startTimeSeconds = startTimeSeconds{
startTime = (startTime ?? 0) + startTimeSeconds
}
if let finalTimeHours = finalTimeHours{
finalTime = (finalTimeHours * 60.0)
}
if let finalTimeMinutes = finalTimeMinutes{
finalTime = (finalTime ?? 0) * 60.0 + finalTimeMinutes * 60.0
}
if let finalTimeSeconds = finalTimeSeconds{
finalTime = (finalTime ?? 0) + finalTimeSeconds
}
let length = Float(asset.duration.value) / Float(asset.duration.timescale)
print("video length: \(length) seconds")
let fileManager = FileManager.default
guard let documentDirectory = try? fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else { return }
var outputURL = documentDirectory.appendingPathComponent("output")
do {
try fileManager.createDirectory(at: outputURL, withIntermediateDirectories: true, attributes: nil)
outputURL = outputURL.appendingPathComponent("\(outputFileName).m4a")
}catch let error {
print(error)
}
//Remove previous existing file
_ = try? fileManager.removeItem(at: outputURL)
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A) else {return}
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.m4a
let start = startTime
let end = finalTime
let startTimeRange = CMTime(seconds: Double(start ?? 0), preferredTimescale: 1000)
let endTimeRange = CMTime(seconds: Double(end ?? length), preferredTimescale: 1000)
let timeRange = CMTimeRange(start: startTimeRange, end: endTimeRange)
exportSession.timeRange = timeRange
exportSession.exportAsynchronously{
switch exportSession.status {
case .completed:
print("exported at \(outputURL)")
case .failed:
print("failed \(String(describing: exportSession.error))")
case .cancelled:
print("cancelled \(String(describing: exportSession.error))")
default:
break
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
guard let path = Bundle.main.path(forResource: "audio", ofType: "m4a") else {
fatalError("Can not get path")
}
let url = URL(fileURLWithPath: path)
asset = AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey : true])
}
}