tvOS:无论如何要在 AVPlayer 之外显示字幕?
tvOS: Anyway to display a subtitle outside of the AVPlayer?
所以场景是有一个视图,用户可以在我帮助开发的应用程序中 enable/disable 字幕。
在那个视图上有一个示例文本 "This is what captions look like",目前它只是一个基本的、无样式的 UILabel
。理想情况下,我希望它的样式与用户在系统设置中自定义字幕的方式类似。
这有可能吗?我设想了两种可能的方法:
创建一个 AVPlayer 实例和一个带有文本的 .vtt 文件,将其加载到视图中并暂停播放器。我不确定示例视频是否可行(并且它必须是透明的,因为示例子文本后面有图像)。
以某种方式获取用户为其字幕设置的所有样式(字体、大小、背景颜色等),并创建一个属性字符串来匹配
方法2似乎是最可行的方法,但我不知道我们是否可以在代码中访问这些设置。
所以我想通了!它基本上结合了 Media Accessibility API,它允许您获取用户为其 captions/subtitle 设置选择的值、属性字符串和子类 UILabel
(尽管这可能 也许 被替换为 UITextView
因为这将允许您将其设置为 UIEdgeInsets
本机)
所以,首先,子类是允许插入UILabel
。这是因为字幕可以有背景颜色和文本高亮颜色,如果没有插图,你只能看到文本高亮。所以子类的功能很简单:
class InsetUILabel: UILabel {
override func drawTextInRect(rect: CGRect) {
let inset: CGFloat = 15
let insets: UIEdgeInsets = UIEdgeInsets(top: inset, left: inset/2, bottom: inset, right: inset/2)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
}
并用于生成实际标签。这使用了一个名为 textSample
的标签,但您显然可以使它更通用一些。
import MediaAccessibility
func styleLabel(sampleText: String) {
let domain = MACaptionAppearanceDomain.User
// Background styling
let backgroundColor = UIColor(CGColor: MACaptionAppearanceCopyWindowColor(domain, nil).takeRetainedValue())
let backgroundOpacity = MACaptionAppearanceGetWindowOpacity(domain, nil)
textSample.layer.backgroundColor = backgroundColor.colorWithAlphaComponent(backgroundOpacity).CGColor
textSample.layer.cornerRadius = MACaptionAppearanceGetWindowRoundedCornerRadius(domain, nil)
// Text styling
var textAttributes = [String:AnyObject]()
let fontDescriptor = MACaptionAppearanceCopyFontDescriptorForStyle(domain, nil, MACaptionAppearanceFontStyle.Default).takeRetainedValue()
let fontName = CTFontDescriptorCopyAttribute(fontDescriptor, "NSFontNameAttribute") as! String
let fontColor = UIColor(CGColor: MACaptionAppearanceCopyForegroundColor(domain, nil).takeRetainedValue())
let fontOpacity = MACaptionAppearanceGetForegroundOpacity(domain, nil)
let textEdgeStyle = MACaptionAppearanceGetTextEdgeStyle(domain, nil)
let textHighlightColor = UIColor(CGColor: MACaptionAppearanceCopyBackgroundColor(domain, nil).takeRetainedValue())
let textHighlightOpacity = MACaptionAppearanceGetBackgroundOpacity(domain, nil)
let textEdgeShadow = NSShadow()
textEdgeShadow.shadowColor = UIColor.blackColor()
let shortShadowOffset: CGFloat = 1.5
let shadowOffset: CGFloat = 3.5
switch(textEdgeStyle) {
case .None:
textEdgeShadow.shadowColor = UIColor.clearColor()
case .DropShadow:
textEdgeShadow.shadowOffset = CGSize(width: -shortShadowOffset, height: shortShadowOffset)
textEdgeShadow.shadowBlurRadius = 6
case .Raised:
textEdgeShadow.shadowOffset = CGSize(width: 0, height: shadowOffset)
textEdgeShadow.shadowBlurRadius = 5
case .Depressed:
textEdgeShadow.shadowOffset = CGSize(width: 0, height: -shadowOffset)
textEdgeShadow.shadowBlurRadius = 5
case .Uniform:
textEdgeShadow.shadowColor = UIColor.clearColor()
textAttributes[NSStrokeColorAttributeName] = UIColor.blackColor()
textAttributes[NSStrokeWidthAttributeName] = -2.0
default:
break
}
textAttributes[NSFontAttributeName] = UIFont(name: fontName, size: (textSample.font?.pointSize)!)
textAttributes[NSForegroundColorAttributeName] = fontColor.colorWithAlphaComponent(fontOpacity)
textAttributes[NSShadowAttributeName] = textEdgeShadow
textAttributes[NSBackgroundColorAttributeName] = textHighlightColor.colorWithAlphaComponent(textHighlightOpacity)
textSample.attributedText = NSAttributedString(string: sampleText, attributes: textAttributes)
}
现在文本高亮部分使用了阴影,我认为这些值看起来很不错,但您可能需要稍微调整一下。希望这对您有所帮助!
所以场景是有一个视图,用户可以在我帮助开发的应用程序中 enable/disable 字幕。
在那个视图上有一个示例文本 "This is what captions look like",目前它只是一个基本的、无样式的 UILabel
。理想情况下,我希望它的样式与用户在系统设置中自定义字幕的方式类似。
这有可能吗?我设想了两种可能的方法:
创建一个 AVPlayer 实例和一个带有文本的 .vtt 文件,将其加载到视图中并暂停播放器。我不确定示例视频是否可行(并且它必须是透明的,因为示例子文本后面有图像)。
以某种方式获取用户为其字幕设置的所有样式(字体、大小、背景颜色等),并创建一个属性字符串来匹配
方法2似乎是最可行的方法,但我不知道我们是否可以在代码中访问这些设置。
所以我想通了!它基本上结合了 Media Accessibility API,它允许您获取用户为其 captions/subtitle 设置选择的值、属性字符串和子类 UILabel
(尽管这可能 也许 被替换为 UITextView
因为这将允许您将其设置为 UIEdgeInsets
本机)
所以,首先,子类是允许插入UILabel
。这是因为字幕可以有背景颜色和文本高亮颜色,如果没有插图,你只能看到文本高亮。所以子类的功能很简单:
class InsetUILabel: UILabel {
override func drawTextInRect(rect: CGRect) {
let inset: CGFloat = 15
let insets: UIEdgeInsets = UIEdgeInsets(top: inset, left: inset/2, bottom: inset, right: inset/2)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
}
并用于生成实际标签。这使用了一个名为 textSample
的标签,但您显然可以使它更通用一些。
import MediaAccessibility
func styleLabel(sampleText: String) {
let domain = MACaptionAppearanceDomain.User
// Background styling
let backgroundColor = UIColor(CGColor: MACaptionAppearanceCopyWindowColor(domain, nil).takeRetainedValue())
let backgroundOpacity = MACaptionAppearanceGetWindowOpacity(domain, nil)
textSample.layer.backgroundColor = backgroundColor.colorWithAlphaComponent(backgroundOpacity).CGColor
textSample.layer.cornerRadius = MACaptionAppearanceGetWindowRoundedCornerRadius(domain, nil)
// Text styling
var textAttributes = [String:AnyObject]()
let fontDescriptor = MACaptionAppearanceCopyFontDescriptorForStyle(domain, nil, MACaptionAppearanceFontStyle.Default).takeRetainedValue()
let fontName = CTFontDescriptorCopyAttribute(fontDescriptor, "NSFontNameAttribute") as! String
let fontColor = UIColor(CGColor: MACaptionAppearanceCopyForegroundColor(domain, nil).takeRetainedValue())
let fontOpacity = MACaptionAppearanceGetForegroundOpacity(domain, nil)
let textEdgeStyle = MACaptionAppearanceGetTextEdgeStyle(domain, nil)
let textHighlightColor = UIColor(CGColor: MACaptionAppearanceCopyBackgroundColor(domain, nil).takeRetainedValue())
let textHighlightOpacity = MACaptionAppearanceGetBackgroundOpacity(domain, nil)
let textEdgeShadow = NSShadow()
textEdgeShadow.shadowColor = UIColor.blackColor()
let shortShadowOffset: CGFloat = 1.5
let shadowOffset: CGFloat = 3.5
switch(textEdgeStyle) {
case .None:
textEdgeShadow.shadowColor = UIColor.clearColor()
case .DropShadow:
textEdgeShadow.shadowOffset = CGSize(width: -shortShadowOffset, height: shortShadowOffset)
textEdgeShadow.shadowBlurRadius = 6
case .Raised:
textEdgeShadow.shadowOffset = CGSize(width: 0, height: shadowOffset)
textEdgeShadow.shadowBlurRadius = 5
case .Depressed:
textEdgeShadow.shadowOffset = CGSize(width: 0, height: -shadowOffset)
textEdgeShadow.shadowBlurRadius = 5
case .Uniform:
textEdgeShadow.shadowColor = UIColor.clearColor()
textAttributes[NSStrokeColorAttributeName] = UIColor.blackColor()
textAttributes[NSStrokeWidthAttributeName] = -2.0
default:
break
}
textAttributes[NSFontAttributeName] = UIFont(name: fontName, size: (textSample.font?.pointSize)!)
textAttributes[NSForegroundColorAttributeName] = fontColor.colorWithAlphaComponent(fontOpacity)
textAttributes[NSShadowAttributeName] = textEdgeShadow
textAttributes[NSBackgroundColorAttributeName] = textHighlightColor.colorWithAlphaComponent(textHighlightOpacity)
textSample.attributedText = NSAttributedString(string: sampleText, attributes: textAttributes)
}
现在文本高亮部分使用了阴影,我认为这些值看起来很不错,但您可能需要稍微调整一下。希望这对您有所帮助!