我一直在扩展我对视频渲染代码的测试,并在使用AVPlayerItemVideoOutput进行测试时发现了一些异常。在尝试测试我的渲染代码时,我使用hasNewPixelBufferForItemTime检查新的像素缓冲区。
测试时,此方法永远不会返回yes。但是渲染代码可以在我的应用程序中使用相同的设置,将帧渲染为openGL纹理。
我设置了一个github项目,其中包含显示错误的基础知识。在应用程序中,您可以通过点击按钮加载视频(不立即加载以避免与测试发生任何冲突)。这至少证明了视频的加载和播放。
该项目还有测试,尝试设置AVPlayerItemVideoOutput并检查新的像素缓冲区。此测试总是失败,但我无法看到我做错了什么,或者为什么完全相同的步骤在我自己的应用中有效。
这是仔细阅读的测试方法:
#import <XCTest/XCTest.h>
#import <AVFoundation/AVFoundation.h>
@interface AVPlayerTestTests : XCTestCase
@end
@implementation AVPlayerTestTests
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void) testAVPlayer
{
NSURL *fileURL = [[NSBundle bundleForClass:self.class] URLForResource:@"SampleVideo_1280x720_10mb" withExtension:@"mp4"];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:fileURL];
[self keyValueObservingExpectationForObject:playerItem
keyPath:@"status" handler:^BOOL(id _Nonnull observedObject, NSDictionary * _Nonnull change) {
AVPlayerItem *oPlayerItem = (AVPlayerItem *)observedObject;
switch (oPlayerItem.status) {
case AVPlayerItemStatusFailed:
{
XCTFail(@"Video failed");
return YES;
}
break;
case AVPlayerItemStatusUnknown:
return NO;
break;
case AVPlayerItemStatusReadyToPlay:
{
return YES;
}
default:
break;
}
}];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
NSDictionary *pbOptions = @{
(NSString *)kCVPixelBufferPixelFormatTypeKey : [NSNumber numberWithInt:kCVPixelFormatType_32BGRA],
(NSString *)kCVPixelBufferIOSurfacePropertiesKey : [NSDictionary dictionary],
(NSString *)kCVPixelBufferOpenGLESCompatibilityKey : @YES
};
AVPlayerItemVideoOutput *output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pbOptions];
XCTAssertNotNil(output);
[self waitForExpectationsWithTimeout:100 handler:nil];
if (playerItem.status == AVPlayerItemStatusReadyToPlay) {
[playerItem addOutput:output];
player.rate = 1.0;
player.muted = YES;
[player play];
CMTime vTime = [output itemTimeForHostTime:CACurrentMediaTime()];
// This is what we're testing
BOOL foundFrame = [output hasNewPixelBufferForItemTime:vTime];
XCTAssertTrue(foundFrame);
if (!foundFrame) {
// Cycle over for ten seconds
for (int i = 0; i < 10; i++) {
sleep(1);
vTime = [output itemTimeForHostTime:CACurrentMediaTime()];
foundFrame = [output hasNewPixelBufferForItemTime:vTime];
if (foundFrame) {
NSLog(@"Got frame at %i", i);
break;
}
if (i == 9) {
XCTFail(@"Failed to acquire");
}
}
}
}
}
@end
编辑1:这似乎是一个错误,我已经提交了雷达