无法在循环中获取AVMutableComposition来播放循环

时间:2012-05-29 17:43:55

标签: iphone objective-c loops avplayer avmutablecomposition

适用于iOS的Xcode

我遇到的问题是播放AVMutableComposition。我正在创建组合,然后在for循环中添加AVURLAssets。我正在添加所有内容,因为我会同样将一个对象添加到一个可变数组,然后尝试播放它,但是没有播放。这是我的代码:

AVMutableComposition *composition = [AVMutableComposition composition];

int count;

count = array.count;

for (int y=0;y<count;y++){    

        NSURL *url;

            url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.mp3", [[NSBundle mainBundle] resourcePath],[array objectAtIndex:y]]];





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

        AVURLAsset *sourceAsset = [[AVURLAsset alloc] initWithURL:url options:options];

        //calculate times
        NSNumber *time = [soundArray1 objectAtIndex:1];

        double timenow = [time doubleValue];
        double insertTime = (240*y);

        CMTime douTime = CMTimeMake(240, timenow);
        CMTime staTime = CMTimeMake(0, 1);
        CMTimeRange editRange = CMTimeRangeMake(staTime,douTime);

        CMTime insTime = CMTimeMake(insertTime, timenow);


        NSError *editError;


        [composition insertTimeRange:editRange ofAsset:sourceAsset atTime:insTime error:&editError];

    }


AVPlayer* mp = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithAsset:composition]];


[mp play];

我认为我完全错了,但是我在循环中添加了这个而不是之后,在if内部并打开一个NSRunLoop来检查(有点不好,但它只是为了测试!):

    AVMutableComposition *composition = [AVMutableComposition composition];

int count;

count = array.count;

for (int y=0;y<count;y++){    

        NSURL *url;

            url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.mp3", [[NSBundle mainBundle] resourcePath],[array objectAtIndex:y]]];





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

        AVURLAsset *sourceAsset = [[AVURLAsset alloc] initWithURL:url options:options];

        //calculate times
        NSNumber *time = [soundArray1 objectAtIndex:1];

        double timenow = [time doubleValue];
        double insertTime = (240*y);

        CMTime douTime = CMTimeMake(240, timenow);
        CMTime staTime = CMTimeMake(0, 1);
        CMTimeRange editRange = CMTimeRangeMake(staTime,douTime);

        CMTime insTime = CMTimeMake(insertTime, timenow);


        NSError *editError;


        [composition insertTimeRange:editRange ofAsset:sourceAsset atTime:insTime error:&editError];



    if(y==3){

    AVPlayer* mp = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithAsset:composition]];


    [mp play];


    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:20]];

        }
    }

在这里,我只给了我的阵列4个元素,并让它在第4次播出时播放。它以完美的顺序工作并播放了我的4个音频文件。

我需要做什么才能让我的作品在循环之后而不是在循环中播放?我误用了系统吗?

编辑:通过在最后粘贴我打开的RunLoop代码,它会播放。我应该这样做,还是有更好的方法来做到这一点?

1 个答案:

答案 0 :(得分:0)

所以我以错误的方式解决这个问题。我需要为每个元素创建一个AVMutableCompositionTrack并将其添加到我的合成

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

        AVURLAsset *sourceAsset = [[AVURLAsset alloc] initWithURL:url options:options];

        //calculate times
        NSNumber *time = [soundArray1 objectAtIndex:1];

        double timenow = [time doubleValue];

        double insertTime = (240*y);

                    AVMutableCompositionTrack *track =
        [composition addMutableTrackWithMediaType:AVMediaTypeAudio
                                 preferredTrackID:kCMPersistentTrackID_Invalid];

        //insert the audio track from the asset into the track added to the mutable composition
        AVAssetTrack *myTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
        CMTimeRange myTrackRange = myTrack.timeRange;
        NSError *error = nil;
        [track insertTimeRange:myTrackRange
                                      ofTrack:myTrack
                                       atTime:CMTimeMake(insertTime, timenow) 
                                        error:&error];

        [sourceAsset release];

接着是

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:composition];
self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];


        [self.player play];

将播放器声明为接口部分中的属性

@interface SecondViewController ()



@property (nonatomic, assign) AVPlayer *player;



@end