No audio is played after saving video with AVCaptureMovieFileOutput
Asked Answered
L

1

8

I try to save a video file from the iphone camera with that following code:

class Camera {

...

private func loadDeviceInput() {
    let devices = AVCaptureDevice.devices() as! [AVCaptureDevice]
    for device in devices {
        if device.hasMediaType(AVMediaTypeVideo) {
            if device.position == .Back {
                _deviceBack = device
                _inputBack  = try? AVCaptureDeviceInput(device: device)
            }
            else if device.position == .Front {
                _deviceFront = device
                _inputFront  = try? AVCaptureDeviceInput(device: device)
            }
        }
        else if device.hasMediaType(AVMediaTypeAudio) {
            _inputAudio = try? AVCaptureDeviceInput(device: device)
        }
    }
}

private func loadDeviceOutput() {
    _outputStill = AVCaptureStillImageOutput()
    _outputStill?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
    if _session.canAddOutput(_outputStill) {
        _session.addOutput(_outputStill)
    }

    _outputAudio = AVCaptureAudioDataOutput()
    if _session.canAddOutput(_outputAudio) {
        _session.addOutput(_outputAudio)
    }

    _outputVideo = AVCaptureMovieFileOutput()
    _outputVideo?.movieFragmentInterval = CMTimeMake(1, 1) // Save file header every second

    if _session.canAddOutput(_outputVideo) {
        _session.addOutput(_outputVideo)
    }
}

func startVideoCapture(writeTo file: NSURL, startedBlock: JrmgxNSURLResultBlock, stopedBlock: JrmgxNSURLResultBlock) {
    isSessionRunning()

    prepareForVideoCapture()
    _startVideoCaptureBlock = startedBlock
    _stopVideoCaptureBlock  = stopedBlock

    if _outputVideo?.connectionWithMediaType(AVMediaTypeVideo)?.active ?? false == true {
        _outputVideo?.startRecordingToOutputFileURL(file, recordingDelegate: self)
    }
    else {
        // ERROR
    }
}

...
}

and so far this is working, but when I playback the video using AVPlayer no sound is played. If I try the video with Quiktime, same problem, no sound. BUT when I open it with VLC, the sound plays.

For reference this is how I play the video, which runs but with no sound:

player = AVPlayer(URL: v)
player.actionAtItemEnd = .None
player.muted = false
player.volume = 1
player.play()

I inspected the video with ffprone:

$ ffprobe test4.mp4 
ffprobe version 2.8.1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test4.mp4':
  Metadata:
    major_brand     : qt  
    minor_version   : 0
    compatible_brands: qt  
    creation_time   : 2016-01-21 13:13:55
  Duration: 00:00:06.37, start: 0.000000, bitrate: 818 kb/s
    Stream #0:0(und): Video: h264 (Baseline) (avc1 / 0x31637661), yuv420p(tv, smpte170m/bt709/bt709), 480x360, 741 kb/s, 30.01 fps, 30 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2016-01-21 13:13:55
      handler_name    : Core Media Video
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 62 kb/s (default)
    Metadata:
      creation_time   : 2016-01-21 13:13:55
      handler_name    : Core Media Audio

I have no idea what is wrong, could you help me?

Thank you

Lavabo answered 21/1, 2016 at 13:56 Comment(4)
I did change the NSURL of the file from video.mp4 to video.mov and the sound now works. If you could explain me why, it will be still appreciated :)Lavabo
I couldn't find in the docs for the AVPlayer , AvPlayerItem or AVAsset , perhaps AVPlayer can not play mp4'sTsarevna
This info may help you differencebetween.net/technology/difference-between-mov-and-mp4Housekeeping
Thank you for theses information, however it does not explain what is happening hereLavabo
V
6

mp4 and mov files are very similar but have subtle differences. i think VLC is simply realizing that the file is actually a .mov and then playing it accordingly, but AVPlayer isn't picking up on it.

you are using AVCaptureMovieFileOutput to save the video and its documentation states:

AVCaptureMovieFileOutput is a concrete sub-class of AVCaptureFileOutput you use to capture data to a QuickTime movie.

a bit of research into what a QuickTime movie is reveals that its standard file extension is .mov:

Save as QuickTime movie – This option will save the embedded video in a *.mov file format no matter what the original container is/was.

if you save the file as a .mov there shouldn't be problems anymore.

Villainage answered 31/1, 2016 at 8:33 Comment(4)
Do you have any idea/example of a concrete implementation for a mp4 FileOutput?Lavabo
AVCaptureVideoDataOutput - example of saving a video to mp4 can be found here: gdcl.co.uk/2013/02/20/iPhone-Pause.htmlVillainage
You saved my day. Thank you.Dourine
Take me days to found this answer. Thank you!Philana

© 2022 - 2024 — McMap. All rights reserved.