我正在开发一款适用于iPad的iOS应用程序,需要在屏幕的某些部分播放视频.我有几个视频文件需要按照编译时未给出的顺序互相播放.它看起来好像只是一个视频播放.从一个视频转到另一个视频是很好的,这是两个视频的最后一帧或第一帧显示的延迟,但是没有闪烁或没有内容的白色屏幕.视频不包含音频.考虑内存使用情况非常重要.视频具有非常高的分辨率,并且可以同时彼此相邻地播放几个不同的视频序列.
为了获得这个,我已经尝试了一些解决方案.它们列在下面:
在这个解决方案中,我有一个AVPlayer,只能在AVPlayerItem上使用AVComposition制作,AVComposition包含彼此相邻的所有视频.当我去特定的视频时,我会在下一个视频开始的构图中寻找时间.这个解决方案的问题是,当寻找时,播放器将快速显示它正在寻找的一些帧,这是不可接受的.似乎没有办法直接跳到合成中的特定时间.我尝试通过制作刚完成的视频中最后一帧的图像来解决这个问题,然后在搜索时显示在AVPLayer前面,最后在搜索完成后删除它.我使用AVAssetImageGenerator制作图像,但由于某种原因,图像的质量与视频不同,因此在视频上显示和隐藏图像时会有显着的变化.另一个问题是AVPlayer使用大量内存,因为单个AVPlayerItem包含所有视频.
此解决方案为每个视频使用AVPlayerItem,并在切换到新视频时替换AVPlayer的项目.这个问题是,当切换AVPlayer的项目时,它会在加载新项目时短时间显示白色屏幕.为了解决这个问题,可以使用在加载时将图像放在最后一帧的前面的解决方案,但仍然存在图像和视频的质量不同且值得注意的问题.
我尝试的下一个解决方案是让两个AVPlayer在彼此之上,轮流播放AVPlayerItems.因此,当玩家完成播放时,它将保留在视频的最后一帧.另一个AVPlayer将被带到前面(其项目设置为nil,因此它是透明的),并且下一个AVPlayerItem将被插入到该AVPlayer中.一旦加载它就会开始播放,两个视频之间顺畅交易的错觉将完好无损.此解决方案的问题是内存使用情况.在某些情况下,我需要同时在屏幕上播放两个视频,这将导致4个AVPlayers同时加载AVPlayerItem.这只是太多的记忆,因为视频可以分辨率非常高.
有没有人有一些关于整体问题和上面发布的尝试解决方案的想法,建议,评论或其他内容.
我正在尝试将CIFilter应用于AVAsset,然后在应用过滤器的情况下保存它.我这样做的方法是使用AVAssetExportSession
with videoComposition
set设置为AVMutableVideoComposition
具有自定义AVVideoCompositing
类的对象.
我还将instructions
我的AVMutableVideoComposition
对象设置为自定义组合指令类(符合AVMutableVideoCompositionInstruction
).这个类传递了一个跟踪ID,以及一些其他不重要的变量.
不幸的是,我遇到了一个问题 - startVideoCompositionRequest:
我的自定义视频合成器类(符合AVVideoCompositing
)中的函数没有被正确调用.
当我将passthroughTrackID
自定义指令类的变量设置为轨道ID时,startVideoCompositionRequest(request)
我的函数AVVideoCompositing
不会被调用.
然而,当我没有设置passthroughTrackID
我的自定义指令类的变量,将startVideoCompositionRequest(request)
被调用,但没有正确-打印request.sourceTrackIDs
结果空数组,并request.sourceFrameByTrackID(trackID)
导致零值.
我发现有趣的是,cancelAllPendingVideoCompositionRequests:
在尝试使用过滤器导出视频时,该函数总是被调用两次.startVideoCompositionRequest:
在startVideoCompositionRequest:
未调用的情况下,它要么被调用一次,要么被调用一次,或者连续两次被调用.
我创建了三个用于导出带过滤器的视频的类.这是实用程序类,它基本上只包含一个export
函数并调用所有必需的代码
class VideoFilterExport{
let asset: AVAsset
init(asset: AVAsset){
self.asset = asset
}
func export(toURL url: NSURL, callback: (url: NSURL?) -> Void){
guard let track: AVAssetTrack = self.asset.tracksWithMediaType(AVMediaTypeVideo).first else{callback(url: nil); return}
let composition …
Run Code Online (Sandbox Code Playgroud) ios avcomposition avvideocomposition avassetexportsession swift
我试图插入指明了AVPlayerItem的AVURLAsset AVPlayerItemStatusReadyToPlay
成AVMutableComposition
这样:
composition_ = [[AVMutableComposition alloc] init];
insertionPoint_ = kCMTimeZero;
item_ = [[AVPlayerItem playerItemWithURL:[NSURL URLWithString:@"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"]] retain];
[item_ addObserver:self forKeyPath:@"status" options:0 context:nil];
player_ = [[AVPlayer playerWithPlayerItem:item_] retain];
[player_ addObserver:self forKeyPath:@"currentItem.duration" options:0 context:nil];
/**
* append a player-item to our composition
*/
- (void)addItemToComposition:(AVPlayerItem *)item
{
NSError *error = nil;
VTRACE(@"item duration: %g", CMTimeGetSeconds(item.duration));
if (![composition_ insertTimeRange:CMTimeRangeMake(kCMTimeZero, item.duration)
ofAsset:item.asset
atTime:insertionPoint_
error:&error])
{
VTRACE(@"error: %@", error);
}
}
/**
* simplified value observer callback
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary …
Run Code Online (Sandbox Code Playgroud) 我有AVMutableComposition
一个视频轨道,我想在视频轨道中添加一个静止图像,以便显示一段时间.静止图像只是一个PNG.我可以将图像作为资产加载,但这就是它,因为结果资产没有任何轨道,因此不能简单地使用这些insertTimeRange…
方法插入.
有没有办法将静止图像添加到合成中?看起来答案在Core Animation的某个地方,但整个事情似乎有点高于我的头脑,我会很感激代码示例或一些信息指针.
我正在尝试使用AVMutableComposition 将图像渲染到使用前置摄像头拍摄的视频中.生成的视频(包括图像)的大小非常好.
但是,初始视频将调整大小,如下图所示:
我正在使用NextLevelSessionExporter,这是我的代码片段:
// * MARK - Creating composition
/// Create AVMutableComposition object. This object will hold the AVMutableCompositionTrack instances.
let mainMutableComposition = AVMutableComposition()
/// Creating an empty video track
let videoTrack = mainMutableComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
let videoAssetTrack = videoAsset.tracks(withMediaType: AVMediaType.video)[0]
do {
//Adding the video track
try videoTrack?.insertTimeRange(CMTimeRange(start: kCMTimeZero, duration: videoAsset.duration), of: videoAsset.tracks(withMediaType: AVMediaType.video).first!, at: kCMTimeZero)
} catch {
completion(false, nil)
}
/// Adding audio if user wants to.
if withAudio {
do …
Run Code Online (Sandbox Code Playgroud) 我们正在开发一款需要通过AVPlayer播放视频文件的应用.文件需要存储在用户的设备上,但也必须在下载时播放.
目前我们已经构建了一个下载模块,该模块使用ASIHTTPRequest库通过PHP获取视频文件(我们不希望媒体可以通过公共URL链接)并将它们异步写入磁盘.
然后我们根据AV Foundation Programming Guide设置AVPlayer ,使用AVURLAsset获取文件,使用资产制作AVPlayerItem,使用项目构建AVPlayer,然后将播放器设置为AVPlayerLayer.播放器在完全下载的视频文件中运行正常,并且还可以在模拟器中完美地运行逐步下载的文件.
不幸的是,在实际设备上,播放器的行为发生了变化,相反,它似乎只加载了一次视频而不会尝试从磁盘中获取新的数据包.结果是播放器将视频和音频播放到视频中的点,该点标记了资源加载时下载进度的位置(例如,如果缓冲了2MB的数据,则创建播放器,播放器将仅播放2MB的数据).因为它有视频的标题,播放器会很高兴地继续认为它在视频的整个持续时间内播放,但没有其他视频呈现在屏幕上.
最后一个问题是,如果将视频插入AVComposition并使用该视频创建AVPlayer,则渐进式视频将正常播放.这将是一个很好的解决方案(无论如何我们的应用程序都是必需的),除了我们的应用程序的客户端要求视频可以通过AirPlay在Apple TV上播放,AVCompositions无法播放.
有没有人知道是否有办法使用AVURLAssets构建的AVPlayer逐步下载视频文件?有没有办法强制播放器/ playerItem使用AVURLAsset从磁盘读取,就像它看起来像AVComposition一样,而不是看似在内存中缓存视频?
谢谢!
我正在做一个项目,该项目需要对大量短(1-5 秒)AVAsset
s进行排序(问题在 n = 30 或更少时可见)。我可以找到的所有参考资料和示例项目都指向使用范围CMTimeRange(start: .zero, end: asset.duration)
插入合成轨道,因此:
let audioTrack: AVAssetTrack = ...
let videoTrack: AVAssetTrack = ...
var playhead = CMTime.zero
for asset in assets {
let assetRange = CMTimeRange(start: .zero, end: asset.duration)
let (sourceAudioTrack, sourceVideoTrack) = sourceTracks(from: asset)
try! audioTrack.insertTimeRange(assetRange, of: sourceAudioTrack, at: playhead)
try! videoTrack.insertTimeRange(assetRange, of: sourceVideoTrack, at: playhead)
playhead = playhead + assetRange.duration
}
Run Code Online (Sandbox Code Playgroud)
问题是这会导致音频和视频不同步(视频似乎滞后于音频。)一些观察:
我已经测试了许多不同的计算时间范围的策略,但似乎都没有解决问题:
enum CompositionStrategy: Int, CaseIterable …
Run Code Online (Sandbox Code Playgroud) 我正在尝试放置一些我正在创建的视频的一部分文本.我意识到我可以使用CALayers在视频的整个长度上使用带有文本的图层,但是如何仅对部分视频执行此操作?经过一些研究,我发现你可以创建一个AVMediaTypeText类型的AVMutableCompositionTrack,看起来这可能就是这个伎俩; 但是,我找不到任何关于如何声明,实例化这样一个轨道的例子?
我这样声明:
AVMutableCompositionTrack *textTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeText preferredTrackID:kCMPersistentTrackID_Invalid];
Run Code Online (Sandbox Code Playgroud)
现在我如何实际添加文本或用字符串实例化?
任何投入赞赏.
我正在获取普通视频的文件 url,但慢动作视频资产类型是AVComposition
. 我正在尝试AVAssetExportSession
但它消耗大量时间。
PHVideoRequestOptions *options=[[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionCurrent;
options.networkAccessAllowed = YES;
[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
if(([avAsset isKindOfClass:[AVComposition class]] && ((AVComposition *)avAsset).tracks.count == 2)) {
//Output URL of the slow motion file.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = paths.firstObject;
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"mergeSlowMoVideo-%d.mov",arc4random() % 1000]];
NSURL *url = [NSURL fileURLWithPath:myPathDocs];
//Begin slow mo video export
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL …
Run Code Online (Sandbox Code Playgroud) 我正在业余时间为 iOS 开发一个视频编辑应用程序。
在参加其他 rpojects 几周后,我刚刚恢复工作,并且 - 即使我没有对代码进行任何重大更改 -现在每次我尝试导出我的视频作品时它都会崩溃。
我检查并构建了我当时成功上传到 TestFlight 的完全相同的提交(并且它在多个设备上工作而没有崩溃),所以这可能是我从那时起更新的最新 Xcode / iOS SDK 的问题?
代码在_xpc_api_misuse上崩溃,在一个线程上:
com.apple.coremedia.basicvideocompositor.output
Run Code Online (Sandbox Code Playgroud)
调试导航器:
在崩溃时,调试导航器上有 70 多个线程,所以可能出现问题并且应用程序使用了太多线程(从未见过这么多)。
我的应用程序使用文本层在导出的视频上覆盖“水印”。玩了一圈后,我发现如果我注释掉水印代码,可以避免崩溃:
guard let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) else {
return failure(ProjectError.failedToCreateExportSession)
}
guard let documents = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {
return failure(ProjectError.temporaryOutputDirectoryNotFound)
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd_HHmmss"
let fileName = dateFormatter.string(from: Date())
let fileExtension = "mov"
let fileURL = …
Run Code Online (Sandbox Code Playgroud) avcomposition ×10
ios ×8
avfoundation ×6
avplayer ×3
avasset ×2
iphone ×2
objective-c ×2
swift ×2
avurlasset ×1
core-video ×1
ios7 ×1