|
@@ -0,0 +1,206 @@
|
|
|
+//
|
|
|
+// File.swift
|
|
|
+// BFFramework
|
|
|
+//
|
|
|
+// Created by ak on 2021/7/13.
|
|
|
+
|
|
|
+import Foundation
|
|
|
+import UIKit
|
|
|
+
|
|
|
+import OpenGLES
|
|
|
+
|
|
|
+import AVFoundation
|
|
|
+
|
|
|
+open class PQGPUImageDebug: BasicOperation {
|
|
|
+ // ui label
|
|
|
+ var subtitleLab: PQSubTitleLabel = PQSubTitleLabel()
|
|
|
+
|
|
|
+ // 全屏模式
|
|
|
+ var isBigSubtile: Bool = false
|
|
|
+
|
|
|
+ // 所有字幕
|
|
|
+ var mSubtitles: [PQEditSubTitleModel]?
|
|
|
+ var subtitleSize: CGSize?
|
|
|
+
|
|
|
+ // 画布大小
|
|
|
+ var inputCGSize: CGSize = .zero
|
|
|
+ // 字幕gpu texture
|
|
|
+ var subTitleTexture: GLuint = 0
|
|
|
+ var subtitleImage: UIImage?
|
|
|
+
|
|
|
+ var lastSubtitle: PQEditSubTitleModel?
|
|
|
+
|
|
|
+ deinit {
|
|
|
+ FilterLog(message: "字幕析构 ")
|
|
|
+ clearData()
|
|
|
+ }
|
|
|
+
|
|
|
+ init(inputSize: CGSize) {
|
|
|
+ super.init(fragmentShader: AlphaPassthroughFragmentShader, numberOfInputs: 1)
|
|
|
+
|
|
|
+ BFLog(message: "isBigSubtile 强制设置 \(isBigSubtile)")
|
|
|
+
|
|
|
+ subTitleTexture = 0
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ func getWidthWithTitle(text: String, font: UIFont) -> CGFloat {
|
|
|
+ let label = UILabel(frame: CGRect(x: 0, y: 0, width: inputCGSize.width * 0.8, height: 0))
|
|
|
+ label.text = text
|
|
|
+ label.font = font
|
|
|
+ label.sizeToFit()
|
|
|
+ let width = label.frame.size.width
|
|
|
+
|
|
|
+ return width
|
|
|
+ }
|
|
|
+
|
|
|
+ func setupLabel(text: String) {
|
|
|
+ var boundingRect: CGRect = .zero
|
|
|
+
|
|
|
+ // 小字幕字号大小
|
|
|
+ var font: Int = 60
|
|
|
+ if inputCGSize.width / inputCGSize.height > 1.5 {
|
|
|
+ font = 68
|
|
|
+ }
|
|
|
+// if !isBigSubtile {
|
|
|
+ boundingRect = text.boundingRect(with: CGSize(width: inputCGSize.width * 0.8, height: 0), options: .usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: CGFloat(114))], context: nil)
|
|
|
+// }
|
|
|
+
|
|
|
+ let strokeWidth: CGFloat = 6
|
|
|
+
|
|
|
+ subtitleLab = PQSubTitleLabel(frame: CGRect(x: 0, y: 0, width: inputCGSize.width * 0.8, height: boundingRect.height > inputCGSize.height - 120 ? inputCGSize.height - 120 : boundingRect.height))
|
|
|
+ subtitleLab.strokeColor = UIColor.black
|
|
|
+ subtitleLab.strokeWidth = strokeWidth
|
|
|
+
|
|
|
+ subtitleLab.font = UIFont.boldSystemFont(ofSize: CGFloat(isBigSubtile ? 114 : font))
|
|
|
+ subtitleLab.numberOfLines = 0
|
|
|
+
|
|
|
+ FilterLog(message: "字幕初始化时大小 \(subtitleLab.frame)")
|
|
|
+
|
|
|
+ subtitleLab.textAlignment = .center
|
|
|
+ subtitleLab.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.5)
|
|
|
+
|
|
|
+ subtitleLab.alpha = 1
|
|
|
+ subtitleLab.textColor = UIColor.white
|
|
|
+ subtitleLab.text = text
|
|
|
+ }
|
|
|
+
|
|
|
+ // 把 UIVIEW 转到 texture
|
|
|
+ func getSubtitleImage(view: UIView) {
|
|
|
+ autoreleasepool {
|
|
|
+ let size: CGSize = view.bounds.size
|
|
|
+ UIGraphicsBeginImageContextWithOptions(size, false, 1)
|
|
|
+ view.layer.render(in: UIGraphicsGetCurrentContext()!)
|
|
|
+
|
|
|
+ subtitleImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
|
|
|
+ UIGraphicsEndImageContext()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清空数据
|
|
|
+ func clearData() {
|
|
|
+ BFLog(message: "清空字幕数据!")
|
|
|
+ subtitleImage = nil
|
|
|
+ glDeleteTextures(1, &subTitleTexture)
|
|
|
+ subTitleTexture = 0
|
|
|
+ lastSubtitle = nil
|
|
|
+ }
|
|
|
+
|
|
|
+ func update(text :String) {
|
|
|
+ setupLabel(text: text)
|
|
|
+
|
|
|
+ getSubtitleImage(view: subtitleLab)
|
|
|
+ }
|
|
|
+
|
|
|
+ func createTexture(text: String) {
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ FilterLog(message: "value istimescale is \(text)")
|
|
|
+
|
|
|
+ self.update(text: text)
|
|
|
+
|
|
|
+ self.subtitleSize = self.subtitleLab.frame.size
|
|
|
+
|
|
|
+ if self.subtitleImage?.cgImage != nil, self.subTitleTexture == 0 {
|
|
|
+ sharedImageProcessingContext.runOperationSynchronously {
|
|
|
+ autoreleasepool {
|
|
|
+ self.subTitleTexture = PQGPUImageTools.setupTexture(image: self.subtitleImage!.cgImage!)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ func createTexture(currtime: CMTime) {
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ FilterLog(message: "value istimescale is \(currtime)")
|
|
|
+
|
|
|
+// self.update(withTimestamp: currtime)
|
|
|
+
|
|
|
+ self.subtitleSize = self.subtitleLab.frame.size
|
|
|
+
|
|
|
+ if self.subtitleImage?.cgImage != nil, self.subTitleTexture == 0 {
|
|
|
+ sharedImageProcessingContext.runOperationSynchronously {
|
|
|
+ autoreleasepool {
|
|
|
+ self.subTitleTexture = PQGPUImageTools.setupTexture(image: self.subtitleImage!.cgImage!)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override public func newFramebufferAvailable(_ framebuffer: Framebuffer, fromSourceIndex: UInt) {
|
|
|
+ super.newFramebufferAvailable(framebuffer, fromSourceIndex: fromSourceIndex)
|
|
|
+
|
|
|
+ let inputSize = framebuffer.sizeForTargetOrientation(.portrait)
|
|
|
+ inputCGSize = CGSize(width: CGFloat(inputSize.width), height: CGFloat(inputSize.height))
|
|
|
+
|
|
|
+ let value: Double = Double(framebuffer.timingStyle.timestamp?.value ?? 0)
|
|
|
+ let timescale: Double = Double(framebuffer.timingStyle.timestamp?.timescale ?? 0)
|
|
|
+
|
|
|
+ let currtime: CMTime = CMTime(value: CMTimeValue(value), timescale: CMTimeScale(timescale))
|
|
|
+
|
|
|
+// createTexture(currtime: currtime)
|
|
|
+ }
|
|
|
+
|
|
|
+ override open func renderFrame() {
|
|
|
+ let inputFramebuffer: Framebuffer = inputFramebuffers[0]!
|
|
|
+ let inputSize = inputFramebuffer.sizeForTargetOrientation(.portrait)
|
|
|
+
|
|
|
+ let currTime = CMTimeGetSeconds(CMTime(value: inputFramebuffer.timingStyle.timestamp!.value, timescale: inputFramebuffer.timingStyle.timestamp!.timescale))
|
|
|
+ FilterLog(message: "subtitle 当前时间: \(currTime)")
|
|
|
+
|
|
|
+ // 原有画布
|
|
|
+ renderFramebuffer = sharedImageProcessingContext.framebufferCache.requestFramebufferWithProperties(orientation: .portrait, size: inputSize, stencil: false)
|
|
|
+
|
|
|
+ let textureProperties = InputTextureProperties(textureCoordinates: inputFramebuffer.orientation.rotationNeededForOrientation(.portrait).textureCoordinates(), texture: inputFramebuffer.texture)
|
|
|
+
|
|
|
+ renderFramebuffer.activateFramebufferForRendering()
|
|
|
+ clearFramebufferWithColor(backgroundColor)
|
|
|
+ renderQuadWithShader(shader, uniformSettings: uniformSettings,
|
|
|
+ vertexBufferObject: sharedImageProcessingContext.standardImageVBO, inputTextures: [textureProperties])
|
|
|
+ releaseIncomingFramebuffers()
|
|
|
+
|
|
|
+ if subTitleTexture != 0 {
|
|
|
+ FilterLog(message: "UIElementFramebuffer 有值可以正常显示")
|
|
|
+ let texturePropertiesimagetwo = InputTextureProperties(textureCoordinates: inputFramebuffer.orientation.rotationNeededForOrientation(.portrait).textureCoordinates(), texture: subTitleTexture)
|
|
|
+
|
|
|
+ FilterLog(message: "subtitleSize subtitleSize is\(String(describing: subtitleSize)) \(inputCGSize)")
|
|
|
+
|
|
|
+ let size: CGSize = inputCGSize
|
|
|
+ let bounds2: CGRect = CGRect(x: (inputCGSize.width - subtitleSize!.width) / 2, y: inputCGSize.height - subtitleSize!.height - 60, width: subtitleSize!.width, height: subtitleSize!.height)
|
|
|
+ FilterLog(message: "inputCGSize is \(size) bounds2\(bounds2)")
|
|
|
+ renderQuadWithShader(shader,
|
|
|
+ uniformSettings: uniformSettings,
|
|
|
+ vertexBufferObject: PQGPUImageTools.NXGenerateVBO(for: PQGPUImageTools.computeVertices(viewSize: inputCGSize, _bounds: CGRect(x: (inputCGSize.width - subtitleSize!.width) / 2, y: isBigSubtile ? (inputCGSize.height - subtitleSize!.height - 60) / 2 : inputCGSize.height - subtitleSize!.height - 60, width: subtitleSize!.width, height: subtitleSize!.height))),
|
|
|
+ inputTextures: [texturePropertiesimagetwo])
|
|
|
+
|
|
|
+ releaseIncomingFramebuffers()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override public func transmitPreviousImage(to _: ImageConsumer, atIndex _: UInt) {
|
|
|
+ print("this is running")
|
|
|
+ }
|
|
|
+}
|
|
|
+
|