Вопрос по ios – Использование AVMutableComposition iPhone

2

Я использую приведенный ниже код для последовательной передачи двух видео. Но он не показывает никакого видео в симуляторе, он абсолютно пустой.

Также, как я могу искать через эти два видео. Мол, если одно видео имеет 2 минуты, а второе - 3 минуты. Теперь мне нужно узнать общее время этих видео и просмотреть их. Когда я сдвигаю ползунок до 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 options:options];
    AVURLAsset * asset2 = [[AVURLAsset alloc]initWithURL:url2 options:options];

    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];   
}

Может кто-нибудь сказать мне, что это ошибка в моем коде?

@ Сэм Нет, я не проверял это на реальном устройстве Omer Waqas Khan
Смотрите ответ на этот вопрос:stackoverflow.com/questions/8318422/… djromero
Вы тестировали этот код на устройстве? Sam
AVQueuePlayer? Два AVPlayers? Загрузка файлов в первую очередь? Есть варианты. Вам нужно знать продолжительность каждого видео и сделать некоторые расчеты, прежде чем решить, какое видео воспроизводить и в какое время искать. djromero
@madmw, тогда есть ли другой способ достичь вышеописанного сценария? Omer Waqas Khan

Ваш Ответ

1   ответ
3

Симулятор НЕ МОЖЕТ отображать видео. Ни встроенный UIImagePickerController, ни любой видеоконтроллер не будут работать. Он не реализован и в основном выглядит черным или красным на симуляторе iOS. Вы должны отладить на целевой iOS. Иногда отладка не будет работать должным образом. Используйте NSLog () istead. Это всегда будет работать (т. Е. Если вы компилируете без отладочной информации с использованием кода «release»)

вы можете искать с помощью плеера:

если 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];
});

Надеюсь, это поможет.

Error: User Rate Limit Exceeded Omer Waqas Khan
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Omer Waqas Khan
Error: User Rate Limit Exceeded

Похожие вопросы