我们的目标是在有人点击按钮时立即显示 3-5 秒的视频剪辑。
显示实际视频涉及几秒钟的延迟,这是不可接受的。我们需要让回放感觉是即时的。
将这 3-5 秒转换为动画 PNG 是一个很好的选择,但动画 PNG 在 iPhone 应用程序中不起作用。
现在最好的选择是使用用于创建动画 PNG 的相同图像,并在 JavaScript 中为一系列图像制作动画。
谁能想到更好的选择?
我们的目标是在有人点击按钮时立即显示 3-5 秒的视频剪辑。
显示实际视频涉及几秒钟的延迟,这是不可接受的。我们需要让回放感觉是即时的。
将这 3-5 秒转换为动画 PNG 是一个很好的选择,但动画 PNG 在 iPhone 应用程序中不起作用。
现在最好的选择是使用用于创建动画 PNG 的相同图像,并在 JavaScript 中为一系列图像制作动画。
谁能想到更好的选择?
除非您预先加载它们,否则图像与视频存在相同的问题,在大多数蜂窝网络上至少有 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
我的意思是在超时不完美的情况下包括跳帧。
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;
}
}