0

私たちの目標は、誰かがボタンをタップしたときに、3 ~ 5 秒のビデオ クリップを即座に表示することです。

実際のビデオの表示には、許容できない数秒の遅延が伴います。瞬時に感じられる再生が必要です。

これらの 3 ~ 5 秒をアニメーション PNG に変換することは優れた代替手段ですが、アニメーション PNG は iPhone アプリでは機能しません。

現在の最良の代替手段は、アニメーション PNG の作成に使用したのと同じ画像を取得し、一連の画像を JavaScript でアニメーション化することです。

誰かがより良い代替案を考えることができますか?

4

2 に答える 2

1

それらをプリロードしない限り、画像にはビデオと同じ問題があり、ほとんどのセルラーで少なくとも 700 ミリ秒の遅延があります。

できることは、Google がアニメーションの Doodle に対して行っているのと同じように、画像スプライトをフィルム リールとして機能させることです。基本的に、アニメーション全体を 1 つの長い画像に入れ、それを背景として配置し、JavaScript を使用してフレームごとに背景の位置を進めます。たとえば、3 秒の 200x100 画像を 100 ミリ秒ごとに進めたい場合は、次のようにします。

<div class="thumb" style="background-image: url(vid1.png); width:200px; height:100px" data-frames="30">
</div>

$('.thumb').bind('click', function() {
    var $img = $(this);
    var startTime = Date.now();
    var frames = $img.attr('data-frames');
    var width = $img.width();

    setInterval(function() {
    var frame = Math.round((Date.now() - startTime) / 100) % frames;
        $img.css('background-position', -frame * width + 'px 0';
    }, 100);
});

アップデート

ここでは画像を使用しているだけなので、フォーマットに縛られることはありません。最善の方法は、フィルムストリップを 60% または 85% の JPG として再エンコードし、ファイル サイズを大幅に削減することです。アニメ化しているので、品質はあまり重要ではありません。

更新 2

タイムアウトが完全でない場合に備えて、フレーム スキップを含めるつもりでした。

于 2012-06-15T22:41:37.033 に答える
0

UIImageView は animationImages をサポートしています。これは、すべての意図と目的のためのアニメーション PNG です。@Brianは正しいですが、プリロードしない限り、少し待ち時間があります。

したがって、私のアドバイスはプリロードすることです。

それはビデオにも当てはまります。MPMoviePlayerController をすべて再生するように設定できますが、ボタンが押されるまでビューを追加して再生しないでください。

アニメーション画像のアイデア:

- (void)readySet {

    NSMutableArray *images = [NSMutableArray array];

    for (int i=0; i<kIMAGE_COUNT; i++) {
        NSString *fn = [NSString stringWithFormat:@"image%d.png"];
        UIImage *image = [UIImage imageNamed:fn];
        [images addObject:image];
    }
    self.myUIImageView.animationImages = [NSArray arrayWithArray:images];
}

// go runs fast if we run readySet first
//
- (void)go {

    [self.myUIImageView startAnimating];
}

ビデオのアイデア

// A little more complex because we need to get notified that it's ready to play,
// but the same principal...

- (void)readySet {

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerLoadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];

    MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:url];

    player.shouldAutoplay = NO;
    [player prepareToPlay];
    self.mp = player;
}

- (void)moviePlayerLoadStateChanged:(NSNotification*)notification {

    MPMovieLoadState state = [self.mp loadState];
    if (state & MPMovieLoadStatePlaythroughOK) {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil];

        self.mp.view.frame = CGRect(/* where it will appear */)
    }
}

// go runs fast if we run readySet first (and the movie is ready)
//
- (void)go {

    MPMovieLoadState state = [self.mp loadState];
    if (state & MPMovieLoadStatePlaythroughOK) {
        [self.view addSubview:self.mp.view];
        [self.mp play];
    } else {
        self.mp.shouldAutoplay = YES;
    }
}
于 2012-06-16T04:31:23.247 に答える