• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - 使用 AVMutableComposition iPhone

[复制链接]
菜鸟教程小白 发表于 2022-12-13 13:28:17 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在使用下面的代码,按顺序流式传输两个视频。但它没有在模拟器中显示任何视频,它完全是空白的。

另外,我该如何通过这两个视频进行搜索。比如,如果一个视频是 2 分钟,第二个是 3 分钟。现在我需要获取这些视频的总时间并通过它们进行搜索。当我将 slider 滑动到 4 分钟时,第二个视频应该从第 2 分钟开始播放。

有可能吗?

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSURL *url1 = [NSURL URLWithString"http://www.tools4movies.com/dvd_catalyst_profile_samples/Harold%20Kumar%203%20Christmas%20bionic.mp4"];
    NSURL *url2 = [NSURL URLWithString"http://www.tools4movies.com/dvd_catalyst_profile_samples/Harold%20Kumar%203%20Christmas%20tablet.mp4"];

    NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:AVURLAssetPreferPreciseDurationAndTimingKey];

    AVMutableComposition *composition = [[AVMutableComposition alloc] init];

    asset1 = [[AVURLAsset alloc] initWithURL:url1 optionsptions];
    AVURLAsset * asset2 = [[AVURLAsset alloc]initWithURL:url2 optionsptions];

    CMTime insertionPoint = kCMTimeZero;
    NSError * error = nil;
    composition = [AVMutableComposition composition];

    if (![composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset1.duration) 
                              ofAsset:asset1 
                               atTime:insertionPoint 
                                error:&error]) 
    {
        NSLog(@"error: %@",error);
    }

    insertionPoint = CMTimeAdd(insertionPoint, asset1.duration);

    if (![composition insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset2.duration) 
                              ofAsset:asset2 
                               atTime:insertionPoint 
                                error:&error]) 
    {
        NSLog(@"error: %@",error);
    }

    AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:composition];
    player = [AVPlayer playerWithPlayerItem:item];
    AVPlayerLayer * layer = [AVPlayerLayer playerLayerWithPlayer:player];

    [layer setFrame:CGRectMake(0, 0, 320, 480)];
    [[[self view] layer] addSublayer:layer];
    [player play];   
}

谁能告诉我我的代码有什么错误?



Best Answer-推荐答案


模拟器无法显示视频。内置的 UIImagePickerController 和任何视频 Controller 都不会工作。它没有实现,在 iOS 模拟器上大多显示为黑色或红色。您必须在 iOS 目标上进行调试。有时调试将无法正常工作。使用 NSLog() 代替。这将始终有效(即,如果您使用“发布”代码在没有调试信息的情况下进行编译)

您可以使用播放器进行搜索:

如果 mp 是您的媒体播放器:

[mp pause];
CMTime position = mp.currentTime;

// maybe replace something
[mp replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithAsset:self.composition]];

[mp seekToTime:length];
[mp play];

总结:
编辑:使用合成和播放器项目
寻找:使用播放器

这是一个简短的正式示例,说明如何执行此操作(并且已经是线程安全的):

AVMutableComposition *_composition = [AVMutableComposition composition];

// iterate though all files
// And build mutable composition
for (int i = 0; i < filesCount; i++) {

    AVURLAsset* sourceAsset = nil;

    NSURL* movieURL = [NSURL fileURLWithPath:[paths objectAtIndex:i]];
    sourceAsset = [AVURLAsset URLAssetWithURL:movieURL options:nil];

    // calculate time
    CMTimeRange editRange = CMTimeRangeMake(CMTimeMake(0, 600), sourceAsset.duration);

    NSError *editError;
    BOOL result = [_composition insertTimeRange:editRange
                                        ofAsset:sourceAsset
                                        atTime:_composition.duration
                                        error:&editError];

    dispatch_sync(dispatch_get_main_queue(), ^{

        // maybe you need a progress bar
        self.loaderBar.progress = (float) i / filesCount;
        [self.loaderBar setNeedsDisplay];
     });

}

// make the composition threadsafe if you need it later
self.composition = [[_composition copy] autorelease];

// Player wants mainthread?    
dispatch_sync(dispatch_get_main_queue(), ^{

    mp = [AVPlayer playerWithPlayerItem:[[[AVPlayerItem alloc] initWithAsset:self.composition] autorelease]];

    self.observer = [mp addPeriodicTimeObserverForInterval:CMTimeMake(60, 600) queue:nil usingBlock:^(CMTime time){

        // this is our callback block to set the progressbar
        if (mp.status == AVPlayerStatusReadyToPlay) {

            float actualTime = time.value / time.timescale;

            // avoid division by zero
            if (time.value > 0.) {

                CMTime length = mp.currentItem.asset.duration;
                float lengthTime = length.value / length.timescale;

                if (lengthTime) {

                    self.progressBar.value = actualTime / lengthTime;
                } else {

                        self.progressBar.value = 0.0f;    
                }
            }];
        });

        // the last task must be on mainthread again
        dispatch_sync(dispatch_get_main_queue(), ^{

            // create our playerLayer
            self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:mp];
            self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;  
            self.playerLayer.frame = [self view].layer.bounds;

            // insert into our view (make it visible)
            [[self view].layer insertSublayer:self.playerLayer atIndex:0];
        });

    // and now do the playback, maybe mp is global (self.mp)
    // this depends on your needs
    [mp play];
});

我希望这会有所帮助。

关于ios - 使用 AVMutableComposition iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10383493/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap