0

我们的目标是在有人点击按钮时立即显示 3-5 秒的视频剪辑。

显示实际视频涉及几秒钟的延迟,这是不可接受的。我们需要让回放感觉是即时的。

将这 3-5 秒转换为动画 PNG 是一个很好的选择,但动画 PNG 在 iPhone 应用程序中不起作用。

现在最好的选择是使用用于创建动画 PNG 的相同图像,并在 JavaScript 中为一系列图像制作动画。

谁能想到更好的选择?

4

2 回答 2

1

除非您预先加载它们,否则图像与视频存在相同的问题,在大多数蜂窝网络上至少有 700 毫秒的延迟。

你可以做的是让图像精灵充当电影卷轴,类似于谷歌为他们的动画涂鸦所做的。您基本上将整个动画放在一张长图像中,将其放置为背景,然后使用 JavaScript 将背景位置每帧推进一次。例如,如果您想要每 100 毫秒推进 3 秒 200x100 图像,您可以这样做:

<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 支持动画图像。这是一个用于所有意图和目的的动画 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 回答