我正在尝试使用macOS上的Swift、AVFoundation和AVKit将多部电影的片段编辑到一个剪辑中。以下Swift代码是我正在尝试的一个很好的示例:
import AVFoundation
import AVKit
let source1 = AVAsset(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
let source2 = AVAsset(url: URL(string: "http://techslides.com/demos/sample-videos/small.mp4")!)
let comp = AVMutableComposition()
comp.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
comp.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
func cmtime(_ i: Double) -> CMTime {
return CMTime(seconds: i, preferredTimescale: 600)
}
func insertSecond(into: AVMutableComposition, from: AVAsset, start: CMTime, at: CMTime) throws {
let videoTrack = into.tracks(withMediaType: .video).first!
let audioTrack = into.tracks(withMediaType: .audio).first!
try videoTrack.insertTimeRange(
CMTimeRange(start: start , duration: cmtime(1.0)),
of: from.tracks(withMediaType: .video).first!,
at: at
)
try audioTrack.insertTimeRange(
CMTimeRange(start: start, duration: cmtime(1.0)),
of: from.tracks(withMediaType: .audio).first!,
at: at
)
}
try insertSecond(into: comp, from: source1, start: cmtime(3.0), at: cmtime(0.0))
try insertSecond(into: comp, from: source2, start: cmtime(2.0), at: cmtime(1.0))
try insertSecond(into: comp, from: source1, start: cmtime(100.0), at: cmtime(2.0))
try insertSecond(into: comp, from: source2, start: cmtime(3.0), at: cmtime(3.0))
try insertSecond(into: comp, from: source1, start: cmtime(350.0), at: cmtime(4.0))
if let sess = AVAssetExportSession(asset: comp, presetName: "AVAssetExportPresetHighestQuality") {
sess.outputURL = URL(fileURLWithPath: "/tmp/output.mp4")
sess.outputFileType = .mp4
sess.exportAsynchronously {
print("done")
print(sess.error ?? "success")
}
}
运行此代码确实会成功生成一个output.mp4
文件,并且该文件可以在Quicktime中毫无问题地播放。您应该能够将上述代码粘贴到Playground中以再现视频(源视频都是托管在Web上的公开可用示例视频)。我还将其上传到此处的S3,因此您无需自己运行代码即可下载和分析它。
但是,尝试使用任何其他视频软件打开或处理它会导致错误。
VLC将尝试播放该文件,但处理起来非常困难。视频冻结很多,与音频失同步,包括Quicktime根本不显示的帧,并完全跳过某些部分。
Firefox也会尝试播放该文件,但显然无法正确解码,并且视频输出有问题。播放第一秒钟后,Chrome会冻结。
我尝试使用ff探针
和ffmpeg
进一步诊断。
show_framesoutput.mp
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fe841801800] DTS -24000 < 24000 out of order
[h264 @ 0x7fe843022800] reference count overflow
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] top block unavailable for requested intra mode -1
[h264 @ 0x7fe843022800] error while decoding MB 5 0, bytestream 947
[h264 @ 0x7fe843022800] concealing 3600 DC, 3600 AC, 3600 MV errors in P frame
[h264 @ 0x7fe843022800] mmco: unref short failure
[h264 @ 0x7fe843022800] cabac_init_idc 4 overflow
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] deblocking filter parameters -43 0 out of range
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
尝试使用ffmpeg(ffmpeg-i output.mp4 output.avi)转码到其他格式时,会出现许多警告和错误:
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 73, current: 71; changing to 74. This may result in incorrect timestamps in the output file.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fe1f4802800] DTS -24000 < 24000 out of order
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 74, current: 72; changing to 75. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 75, current: 73; changing to 76. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 76, current: 74; changing to 77. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 77, current: 75; changing to 78. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f4849600] reference count overflow
[h264 @ 0x7fe1f4849600] decode_slice_header error
[h264 @ 0x7fe1f4849600] no frame!
Error while decoding stream #0:1: Invalid data found when processing input
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 145, current: 143; changing to 146. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 146, current: 144; changing to 147. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 147, current: 145; changing to 148. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f483d800] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe1f483d800] decode_slice_header error
[h264 @ 0x7fe1f483d800] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 148, current: 146; changing to 149. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 149, current: 147; changing to 150. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f4849600] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe1f4849600] decode_slice_header error
[h264 @ 0x7fe1f4849600] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 150, current: 148; changing to 151. This may result in incorrect timestamps in the output file.
Error while decoding stream #0:1: Invalid data found when processing input
Last message repeated 1 times
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 151, current: 149; changing to 152. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 152, current: 150; changing to 153. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 153, current: 151; changing to 154. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 154, current: 152; changing to 155. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 155, current: 153; changing to 156. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 156, current: 154; changing to 157. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 157, current: 155; changing to 158. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 158, current: 156; changing to 159. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 159, current: 157; changing to 160. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 160, current: 158; changing to 161. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 161, current: 159; changing to 162. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 162, current: 160; changing to 163. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 163, current: 161; changing to 164. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 164, current: 162; changing to 165. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 165, current: 163; changing to 166. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 166, current: 164; changing to 167. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 167, current: 165; changing to 168. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 168, current: 166; changing to 169. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 169, current: 167; changing to 170. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 170, current: 168; changing to 171. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 171, current: 169; changing to 172. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 172, current: 170; changing to 173. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 173, current: 171; changing to 174. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 174, current: 172; changing to 175. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 175, current: 173; changing to 176. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 176, current: 174; changing to 177. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 177, current: 175; changing to 178. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 178, current: 176; changing to 179. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 179, current: 177; changing to 180. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 180, current: 178; changing to 181. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 181, current: 179; changing to 182. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 182, current: 180; changing to 183. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 183, current: 181; changing to 184. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 184, current: 182; changing to 185. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f483d800] top block unavailable for requested intra mode -1
[h264 @ 0x7fe1f483d800] error while decoding MB 5 0, bytestream 947
[h264 @ 0x7fe1f483d800] concealing 3600 DC, 3600 AC, 3600 MV errors in P frame
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 185, current: 183; changing to 186. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 186, current: 184; changing to 187. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f4849600] mmco: unref short failure
[h264 @ 0x7fe1f4849600] cabac_init_idc 4 overflow
[h264 @ 0x7fe1f4849600] decode_slice_header error
[h264 @ 0x7fe1f4849600] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 187, current: 185; changing to 188. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f485fa00] deblocking filter parameters -43 0 out of range
[h264 @ 0x7fe1f485fa00] decode_slice_header error
[h264 @ 0x7fe1f485fa00] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 188, current: 186; changing to 189. This may result in incorrect timestamps in the output file.
Error while decoding stream #0:1: Invalid data found when processing input
Last message repeated 1 times
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 189, current: 187; changing to 190. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 190, current: 188; changing to 191. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 191, current: 189; changing to 192. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 192, current: 190; changing to 193. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 193, current: 191; changing to 194. This may result in incorrect timestamps in the output file.
上面的代码只是一个例子,我在这段代码的许多变体中看到了严重程度不同的类似问题。我尝试了很多东西,包括:
但没有用——我似乎无法让AVFoundation生成其他工具可以处理的视频文件。
如果您不能或不想自己运行上述Swift代码来重现输出文件,您可以在此处下载任何帮助,甚至是关于输出文件编码的异常之处的任何想法。
这个问题几乎可以肯定是因为视频和音频的剪辑格式不匹配:
AVAssetExportSession
可以做很多事情,但它似乎选择将所有格式转储到其中,这可能解释了您的兼容性问题。我可以理解为什么播放器会感到困惑,这两种视频格式甚至没有相同的长宽比。也许这种行为是一个错误,或者在某些情况下它完全有意义。我不知道。
因此,您可以:
p、 我怀疑视频不匹配比音频更重要,所以测试可能会显示你可以忽略音频?
正如@RhythmicFistman所说,您的视频流是多个具有不同属性的H264流的集合。H264流的参数通常可以存储在带内(称为附件B)或存储在MP4等容器中的全局元数据中(stsd
)。AVF在这里所做的是添加多个stsd条目。
stsd: s= 326 (0x00000146), o= 1982552 (0x001e4058)
version: 0
flags: 0x000000
sample_descriptions (0x00000002):
size: 0000009b
data_format: avc1 (61 76 63 31)
...
size: 0000009b
data_format: avc1 (61 76 63 31)
...
大多数播放器将忽略其他条目,但解码器需要此位流配置进行(重新)初始化。
前进的道路有两条。
用相同的编码属性重新编码每个单独的段,这样在编码后,解码器reinit的缺乏实际上就不是问题,
或
获取AVF或其他工具(如mp4box)将流浓缩为avc3流,从而位流参数也存储在频带中。解码器应该遇到新的参数集并重新输入。
我同意其他播放器的播放问题源于每首曲目有多个格式描述。但实际上在合成之前不需要昂贵的曲目转码,AVFoundation可以为您完成此操作...如果您愿意跳过几个圈。
关键是一个AVMutableComposition可以有多个特定媒体类型的曲目,而AVAssetExportSession可以将这些曲目“混合”到每个媒体类型的一个曲目中。AVFoundation通过提供mutableTrackCompatibleWithTrack:承认了每首曲目有多个格式描述的问题。因此,当您想从给定的源曲目中插入一段时,可以询问AVMutableComposition以获得合适的目标曲目,如果没有返回任何曲目,请添加一个新曲目。
如前所述,有几件事要记住:
>
您不能在当前结束后的“无效时间”的某个位置插入给定的目标轨道。要解决这个问题,请注意目标轨道的当前结束时间,在该时间追加该片段,然后在前一个轨道结束处插入一个持续时间正确的空片段。下面的示例显示了这一点,在简化的假设下,您总是追加。如果您想在现有轨道中的任何位置插入,您需要更详细的逻辑。
要真正让AVAssetExportSession
将所有内容混合到每种媒体类型只有一首曲目,您必须在导出会话上设置AVAudioMix和AVVideoComtion。
下面的示例代码基于原始示例生成一个输出。mp4可以在VLC、Chrome和Firefox中正确播放,使用ffmpeg检查时不会出错。
import AVFoundation
import Foundation
let source0 = AVAsset(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
let source1 = AVAsset(url: URL(string: "http://techslides.com/demos/sample-videos/small.mp4")!)
let comp = AVMutableComposition()
func cmtime(_ i: Double) -> CMTime {
return CMTime(seconds: i, preferredTimescale: 600)
}
func insertTrackSecond( srcAsset: AVAsset, dstComp: AVMutableComposition, mediaType: AVMediaType, start: CMTime, at: CMTime) throws {
let srcTrack: AVAssetTrack = srcAsset.tracks(withMediaType: mediaType).first!
// get a compatible destination track or, if not available, create a new one
let dstTrack: AVMutableCompositionTrack = dstComp.mutableTrack(compatibleWith: srcTrack) ?? dstComp.addMutableTrack(withMediaType: mediaType, preferredTrackID: kCMPersistentTrackID_Invalid)!
// can't insert into "void" time beyond the current end of track. Instead, note current end time, append there, and *after* appending, insert empty range
var dstTrackEnd: CMTime = CMTimeRangeGetEnd( dstTrack.timeRange)
if CMTIME_IS_INVALID( dstTrackEnd) {
dstTrackEnd = kCMTimeZero
}
try dstTrack.insertTimeRange( CMTimeRangeMake( start, cmtime( 1.0)), of: srcTrack, at: dstTrackEnd)
// now add empty range, if necessary
if CMTimeCompare( dstTrackEnd, at) == -1 {
dstTrack.insertEmptyTimeRange( CMTimeRangeFromTimeToTime( dstTrackEnd, at))
}
}
func insertSecond( srcAsset: AVAsset, dstComp: AVMutableComposition, start: CMTime, at: CMTime) throws
{
try insertTrackSecond(srcAsset: srcAsset, dstComp: dstComp, mediaType: .video, start: start, at: at)
try insertTrackSecond(srcAsset: srcAsset, dstComp: dstComp, mediaType: .audio, start: start, at: at)
}
try insertSecond( srcAsset: source0, dstComp: comp, start: cmtime(3.0), at: cmtime(0.0))
try insertSecond( srcAsset: source1, dstComp: comp, start: cmtime(2.0), at: cmtime(1.0))
try insertSecond( srcAsset: source0, dstComp: comp, start: cmtime(100.0), at: cmtime(2.0))
try insertSecond( srcAsset: source1, dstComp: comp, start: cmtime(3.0), at: cmtime(3.0))
try insertSecond( srcAsset: source0, dstComp: comp, start: cmtime(350.0), at: cmtime(4.0))
if let sess = AVAssetExportSession(asset: comp, presetName: "AVAssetExportPresetHighestQuality") {
sess.outputURL = URL(fileURLWithPath: "/tmp/output.mp4")
sess.outputFileType = .mp4
// this leaves smaller videotracks at the origin, in their "natural" size. Manipulate the "preferredTransform" property of the mutable composition tracks for nicer results
sess.videoComposition = AVVideoComposition.init(propertiesOf: comp)
// not assigning an audio mix results in an output with multiple audio tracks
var inputParameters = [AVAudioMixInputParameters]()
for audioTrack: AVAssetTrack in comp.tracks(withMediaType:.audio) {
inputParameters.append( AVMutableAudioMixInputParameters.init(track:audioTrack))
}
let audioMix: AVMutableAudioMix = AVMutableAudioMix();
audioMix.inputParameters = inputParameters;
sess.audioMix = audioMix;
let semaphore: DispatchSemaphore = DispatchSemaphore(value:0);
sess.exportAsynchronously {
print("done")
print(sess.error ?? "success")
semaphore.signal()
}
semaphore.wait()
}
我已经成功地使用ffmpeg将一个文件编码到.mp4,这将在所有测试的设备(Safari on PC,IE on PC,Android Browser、Andriod Video Player和Safari iPad)中播放,但Chrome除外。 作为一种解决办法,我曾计划简单地将.ogg源代码列在.mp4源代码之前,这样chrome就可以播放.ogg源代码,而不会看到.mp4源代码,然而,我遇到
请问,我怎样才能得到一个真正的MP4? 我的代码:
问题内容: 我正在尝试使用中创建视频。但是文件大小为0。 我的代码: 总是回来。 另一种尝试: 没有错误,但输出为空。 我想念什么? 问题答案: 您想要做什么的简单代码。详细内容点击这里
我曾尝试使用GStreamer管道将mp4视频转换为avi视频,但它是在没有声音的情况下转换的 gst launch-t-v filesrc location=源。mp4!qtdemux!ffdec\U h264!视频/x-raw-yuv!avimux!filesink location=结果yuv。avi公司
关于创建视频图像 Photoshop 可以创建具有各种长宽比的图像,以便它们能够在设备(如视频显示器)上正确显示。可以选择特定的视频选项(使用“新建”对话框)以便对将最终图像合并到视频中时进行的缩放提供补偿。 安全区域 “胶片和视频”预设还会创建带有非打印参考线的文档,参考线可画出图像的动作安全区域和标题安全区域的轮廓。使用“大小”菜单中的选项,可以生成用于特定视频系统(NTSC、PAL 或 HD
Motion 是一个支持动作捕获的视频捕捉工具。