编辑3
我找到了根本原因。 CADisplayLink
有强烈的目标参考。所以它使得保留周期。
修改2
现在我认为导致崩溃的内存问题。
我正在做的是捕捉播放器的输出并将其绘制在opengl层上。
AVPlayerItem *item = ...;
if (!self.player) {
self.player = [AVPlayer playerWithPlayerItem:item];
} else {
[self.player replaceCurrentItemWithPlayerItem:item];
}
NSDictionary *pixBuffAttributes = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
self.videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:pixBuffAttributes];
[self.player.currentItem addOutput:self.videoOutput];
[self.player seekToTime:kCMTimeZero];
[self.player play];
在DisplayLink
CMTime itemTime = [self.videoOutput itemTimeForHostTime:CACurrentMediaTime()];
BOOL hasNewContent = [self.videoOutput hasNewPixelBufferForItemTime:itemTime];
if (hasNewContent) {
CVPixelBufferRef pixelBuffer = [self.videoOutput copyPixelBufferForItemTime:itemTime itemTimeForDisplay:NULL];
// creat texture with pixelBuffer
// display texture on opengl surface
if (pixelBuffer != NULL) {
CFRelease(pixelBuffer);
}
}
修改1:
我找到了一个解决方法。 " video_1"的分辨率和" video_3"是3840 * 1920," video_2"是2160 * 1080。
当我使用ffmpeg将所有分辨率更改为2160 * 1080时,它已经有效。
来源
我想按顺序播放几个视频并遇到一种非常奇怪的行为。
AVPlayerItem *item = ...;
if (!self.player) {
self.player = [AVPlayer playerWithPlayerItem:item];
} else {
[self.player replaceCurrentItemWithPlayerItem:item];
}
[self.player seekToTime:kCMTimeZero];
[self.player play];
例如,我有三个视频文件,例如video_1,video_2和video_3。
首先,我使用" video_1"设置playerItem,然后用" video_2"替换。没关系。
但我用" video_3"替换,应用程序已崩溃。我无法在iphone上找到任何设备日志。更重要的是,当我调试并替换为" video_3"时,它会断开调试并且没有例外!
更多信息:
"video_2" can replace "video_1"
"video_1" can replace "video_2"
"video_3" can replace "video_2"
"video_3" can't replace "video_1"
"video_1" can't replace "video_3"
所有视频都可以单独播放。
答案 0 :(得分:0)
尝试下面的代码
if ([playerItemVideoOutput hasNewPixelBufferForItemTime:currentTime]) {
__unsafe_unretained ViewController *weakSelf = self; //create weak reference of your viewcontroller
CVPixelBufferRef pixelBuffer = [playerItemVideoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil];
if(pixelBuffer) { //check if buffer exist
[weakSelf.metalView.realTimeRender setPixelBuffer:pixelBuffer]; //use weakSelf here
CFRelease(pixelBuffer);
}
}