音视频面试题集锦第 30 期

分享来自音视频技术社群关键帧的音视频开发圈的第 30 期面试题精选:

  • 1、为什么自制的动态图片导出到相册无法识别成动态图片?
  • 2、iOS 如何实现音频内录,录制当前所有手机的声音集合?
  • 3、应该选择哪种复杂字体渲染的方案 (非 UIView 的能力)?
  • 4、iOS 如何在不解码的情况下给视频添加 Metadata?

1、为什么自制的动态图片导出到相册无法识别成动态图片?

Live Photo 需要有一个特殊的 Metadata Key [kCGImagePropertyMakerAppleDictionary : [17 : <Identifier>]]

因此需要先将此 Metadata 导入到图片中,然后再导出动态图片,这样图片才会被识别成动态图片。

以下是将此 Metadata 导入到图片的 swift 代码示例:

guard let imageSource = CGImageSourceCreateWithURL(photoURL as CFURL, nil),
let imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, nil),
var imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [AnyHashable : Any] else {
    throw LivePhotosAssembleError.addPhotoIdentifierFailed
}
let identifierInfo = ["17" : identifier]
imageProperties[kCGImagePropertyMakerAppleDictionary] = identifierInfo
guard let imageDestination = CGImageDestinationCreateWithURL(destinationURL as CFURL, UTType.jpeg.identifier as CFString, 1, nil) else {
    throw LivePhotosAssembleError.createDestinationImageFailed
}
CGImageDestinationAddImage(imageDestination, imageRef, imageProperties as CFDictionary)
if CGImageDestinationFinalize(imageDestination) {
    return destinationURL
} else {
    throw LivePhotosAssembleError.createDestinationImageFailed
}

2、iOS 如何实现音频内录,录制当前所有手机的声音集合?

在 iOS 11 中,ReplayKit 提供了强大的能力:将系统作为一个整体进行直播。用户在控制中心内开启屏幕录制后,ReplayKit2 Extension 可以获取到整个系统级的屏幕画面、以及设备所产生的所有音频,实现跨应用录屏(iOS System Boardcast),同时 ReplayKit 也提供了麦克风采集,这种系统级的直播在应用间切换时也不会停止。可以看下图了解 ReplayKit 的流程:

音视频面试题集锦第 30 期
ReplayKit 数据流

用户通过手动点击录制按钮然后选择你的应用,则你的 Extension 即可接收到音视频数据,此时你可以在 Extension 里面做一些简单处理或者上传。

更多的内容可以参考:iOS ReplayKit 与 屏幕录制[1]

3、应该选择哪种复杂字体渲染的方案 (非 UIView 的能力)?

看过多个字体渲染的三方库发现有部分平台上还是使用了系统的能力。因为系统的字体渲染更稳定,性能更高,支持的功能也足够丰富。例如 iOS 使用了 CoreText,高性能,支持高级文本布局和多种字体,并且可以轻松的输出图片。

以下是 CoreText 实现文字渲染然后输出到图片的示例:

CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica-Bold"), 16, NULL);
NSDictionary *attributes = @{(id)kCTFontAttributeName: (__bridge id)font};
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"Hello, World!" attributes:attributes];

CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedString);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 0, 280, 50)); // 定义绘制区域
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);

CGContextRef context = UIGraphicsGetCurrentContext(); // 获取当前图形上下文
int width = 280;
int height = 50;
GLubyte *imageData = (GLubyte *) calloc(1, (int)width * (int)height * 4);
if (!context){
    context = CGBitmapContextCreate(imageData, (size_t)width, (size_t)height, 8, (size_t)width * 4, CGColorSpaceCreateDeviceRGB(),  kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
}
CGContextSetGrayFillColor(context, 1.0f, 1.0f);
CGContextSetTextMatrix(context, CGAffineTransformIdentity); // 设置文本矩阵
UIGraphicsPushContext(context);
[attributedString drawAtPoint:CGPointMake(0 , 0)];
CGImageRef a = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:a]; // 输出结果

CGContextRelease(context);
CFRelease(frame);
CGPathRelease(path);
CFRelease(fontName);
CFRelease(font);

4、iOS 如何在不解码的情况下给视频添加 Metadata?

1、初始化 AVAssetReader,创建对应的 AVAssetReaderTrackOutput,包括 videoReaderOutput、audioReaderOutput。注意 videoReaderOutput 吐出的数据应该是 h264/h265 非解码的数据,audioReaderOutput 也应该是 aac 等非解码格式。

2、初始化 AVAssetWriter,创建及对应的 AVAssetWriterInput,包括 videoWriterInput、audioWriterInput。

3、初始化要添加的 AVMetaDataItem。

4、AVAssetWriter 添加来自 AVAssetWriterInputMetadataAdaptor 的 assetWriterInput。

5、AVAssetWriter 进入写状态。

5、使用 AVAssetReader 和 AVAssetWriterInputMetadataAdaptor 写入准备好的 Metadata。

6、videoReaderOutput、audioReaderOutput、videoWriterInput、audioWriterInput 进入读写写状态。

8、读取完所有数据后,让 AVAssetReader 停止读取。使所有 AVAssetWriterInput 标记完成。

9、等待 AVAssetWriter 变为完成状态,视频创建完成。


更多的音视频知识、面试题、技术方案干货可以进群来看:

音视频面试题集锦第 30 期

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论