Ich versuche, Video aufgenommen mit der Kamera des Benutzers von UIImagePickerController (Nicht ein vorhandenes Video, sondern ein on the fly) auf meinen Server hochladen und nehmen Sie eine kleine Menge Zeit zu tun Also, so eine kleinere Größe ist ideal anstelle von 30-45 mb auf neueren Qualitätskameras.IOS Videokompression Swift iOS 8 korrupte Videodatei
Hier ist der Code, um eine Komprimierung in Swift für iOS 8 zu tun, und es komprimiert wunderbar, ich gehe von 35 mb bis 2,1 mb leicht.
func convertVideo(inputUrl: NSURL, outputURL: NSURL)
{
//setup video writer
var videoAsset = AVURLAsset(URL: inputUrl, options: nil) as AVAsset
var videoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo)[0] as AVAssetTrack
var videoSize = videoTrack.naturalSize
var videoWriterCompressionSettings = Dictionary(dictionaryLiteral:(AVVideoAverageBitRateKey,NSNumber(integer:960000)))
var videoWriterSettings = Dictionary(dictionaryLiteral:(AVVideoCodecKey,AVVideoCodecH264),
(AVVideoCompressionPropertiesKey,videoWriterCompressionSettings),
(AVVideoWidthKey,videoSize.width),
(AVVideoHeightKey,videoSize.height))
var videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoWriterSettings)
videoWriterInput.expectsMediaDataInRealTime = true
videoWriterInput.transform = videoTrack.preferredTransform
var videoWriter = AVAssetWriter(URL: outputURL, fileType: AVFileTypeQuickTimeMovie, error: nil)
videoWriter.addInput(videoWriterInput)
var videoReaderSettings: [String:AnyObject] = [kCVPixelBufferPixelFormatTypeKey:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]
var videoReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
var videoReader = AVAssetReader(asset: videoAsset, error: nil)
videoReader.addOutput(videoReaderOutput)
//setup audio writer
var audioWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: nil)
audioWriterInput.expectsMediaDataInRealTime = false
videoWriter.addInput(audioWriterInput)
//setup audio reader
var audioTrack = videoAsset.tracksWithMediaType(AVMediaTypeAudio)[0] as AVAssetTrack
var audioReaderOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil) as AVAssetReaderOutput
var audioReader = AVAssetReader(asset: videoAsset, error: nil)
audioReader.addOutput(audioReaderOutput)
videoWriter.startWriting()
//start writing from video reader
videoReader.startReading()
videoWriter.startSessionAtSourceTime(kCMTimeZero)
//dispatch_queue_t processingQueue = dispatch_queue_create("processingQueue", nil)
var queue = dispatch_queue_create("processingQueue", nil)
videoWriterInput.requestMediaDataWhenReadyOnQueue(queue, usingBlock: {() -> Void in
println("Export starting")
while videoWriterInput.readyForMoreMediaData
{
var sampleBuffer:CMSampleBufferRef!
sampleBuffer = videoReaderOutput.copyNextSampleBuffer()
if (videoReader.status == AVAssetReaderStatus.Reading && sampleBuffer != nil)
{
videoWriterInput.appendSampleBuffer(sampleBuffer)
}
else
{
videoWriterInput.markAsFinished()
if videoReader.status == AVAssetReaderStatus.Completed
{
if audioReader.status == AVAssetReaderStatus.Reading || audioReader.status == AVAssetReaderStatus.Completed
{
}
else {
audioReader.startReading()
videoWriter.startSessionAtSourceTime(kCMTimeZero)
var queue2 = dispatch_queue_create("processingQueue2", nil)
audioWriterInput.requestMediaDataWhenReadyOnQueue(queue2, usingBlock: {() -> Void in
while audioWriterInput.readyForMoreMediaData
{
var sampleBuffer:CMSampleBufferRef!
sampleBuffer = audioReaderOutput.copyNextSampleBuffer()
println(sampleBuffer == nil)
if (audioReader.status == AVAssetReaderStatus.Reading && sampleBuffer != nil)
{
audioWriterInput.appendSampleBuffer(sampleBuffer)
}
else
{
audioWriterInput.markAsFinished()
if (audioReader.status == AVAssetReaderStatus.Completed)
{
videoWriter.finishWritingWithCompletionHandler({() -> Void in
println("Finished writing video asset.")
self.videoUrl = outputURL
var data = NSData(contentsOfURL: outputURL)!
println("Byte Size After Compression: \(data.length/1048576) mb")
println(videoAsset.playable)
//Networking().uploadVideo(data, fileName: "Test2")
self.dismissViewControllerAnimated(true, completion: nil)
})
break
}
}
}
})
break
}
}
}// Second if
}//first while
})// first block
// return
}
Hier ist der Code für meine UIImagePickerController die
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject])
{
// Extract the media type from selection
let type = info[UIImagePickerControllerMediaType] as String
if (type == kUTTypeMovie)
{
self.videoUrl = info[UIImagePickerControllerMediaURL] as? NSURL
var uploadUrl = NSURL.fileURLWithPath(NSTemporaryDirectory().stringByAppendingPathComponent("captured").stringByAppendingString(".mov"))
var data = NSData(contentsOfURL: self.videoUrl!)!
println("Size Before Compression: \(data.length/1048576) mb")
self.convertVideo(self.videoUrl!, outputURL: uploadUrl!)
// Get the video from the info and set it appropriately.
/*self.dismissViewControllerAnimated(true, completion: {() -> Void in
//self.next.enabled = true
})*/
}
}
die Kompresse Methode ruft Wie ich bereits erwähnt dies, soweit Reduzierung der Dateigröße funktioniert, aber wenn ich die Datei zurück (es ist nach wie vor vom Typ .mov) quicktime kann es nicht abspielen. Quicktime versucht zunächst, es zu konvertieren, schlägt aber in der Mitte (1-2 Sekunden nach dem Öffnen der Datei) fehl. Ich habe sogar die Videodatei in AVPlayerController getestet, aber es gibt keine Informationen über den Film, es ist nur ein Play-Taste ohne ant loading und ohne Länge nur "-" wo die Zeit normalerweise im Player ist. IE eine beschädigte Datei, die nicht abgespielt wird.
Ich bin mir sicher, dass es etwas mit den Einstellungen zum Schreiben des Assets zu tun hat, ob es das Video schreiben oder das Audio schreiben ist, bin ich mir überhaupt nicht sicher. Es könnte sogar das Lesen des Vermögenswerts sein, das dafür sorgt, dass es korrupt wird. Ich habe versucht, die Variablen zu ändern und unterschiedliche Schlüssel zum Lesen und Schreiben zu setzen, aber ich habe nicht die richtige Kombination gefunden und das ist zum Kotzen, dass ich komprimieren kann, aber eine beschädigte Datei daraus bekomme. Ich bin mir überhaupt nicht sicher und jede Hilfe würde geschätzt werden. Pleeeeeeeeeease.
Danke für eine aktualisierte Antwort CodeBender. 20MB bis 500k ist ziemlich erstaunlich. Ich werde dafür sorgen, dass dies verbessert wird. –
Ich habe das versucht, aber ich bekomme immer den Sitzungsstatus als Fehlgeschlagen. – Sneha
@Sneha Ich habe die Antwort für Swift 4.0 aktualisiert. Vielleicht hilft das bei Ihrem Problem? – CodeBender