Skip to content

Instantly share code, notes, and snippets.

@omarojo
Created May 4, 2017 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omarojo/2a4ad26d77cfdcd4f9443216bd9ac696 to your computer and use it in GitHub Desktop.
Save omarojo/2a4ad26d77cfdcd4f9443216bd9ac696 to your computer and use it in GitHub Desktop.
Pause Image for LF Streamer
var pausePixelBuffer = CVPixelBuffer?
func pauseTheStream(){
//Create your Pause Image
createOncePixelBuffer()
//Push your Pause Image into the stream
pushPixelBufferToStream(self.pausePixelBuffer)
//Pause the stream, the video should stop in the last frame, which is your image
rtmpStream.togglePause()
}
func createOncePixelBuffer(){
let myimage = UIImage(named: "myPauseImage")!
self.pausePixelBuffer = pixelBufferFromImage(image: myimage);
}
func pushPixelBufferToStream(pixelBuffer : CVPixelBuffer?){
if let imageBuffer = pixelBuffer {
var timingInfo:CMSampleTimingInfo = CMSampleTimingInfo(
duration: CMTimeMake(1,30),
presentationTimeStamp: self.PTS,
decodeTimeStamp: kCMTimeInvalid
)
var videoFormatDescription:CMVideoFormatDescription? = nil
_ = CMVideoFormatDescriptionCreateForImageBuffer(
kCFAllocatorDefault,
imageBuffer,
&videoFormatDescription
)
var sampleBuffer:CMSampleBuffer? = nil
_ = CMSampleBufferCreateForImageBuffer(
kCFAllocatorDefault,
imageBuffer,
true,
nil,
nil,
videoFormatDescription!,
&timingInfo,
&sampleBuffer
)
if let buffer:CMSampleBuffer = sampleBuffer {
rtmpStream.appendSampleBuffer(buffer, withType: .video);
}
self.PTS = CMTimeAdd(self.PTS, CMTimeMake(1, 30));
}
}
func pixelBufferFromImage(image: UIImage) -> CVPixelBuffer {
let ciimage = CIImage(image: image)
let cgimage = convertCIImageToCGImage(inputImage: ciimage!)
let cfnumPointer = UnsafeMutablePointer<UnsafeRawPointer>.allocate(capacity: 1)
let cfnum = CFNumberCreate(kCFAllocatorDefault, .intType, cfnumPointer)
let keys: [CFString] = [kCVPixelBufferCGImageCompatibilityKey, kCVPixelBufferCGBitmapContextCompatibilityKey, kCVPixelBufferBytesPerRowAlignmentKey]
let values: [CFTypeRef] = [kCFBooleanTrue, kCFBooleanTrue, cfnum!]
let keysPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
let valuesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 1)
keysPointer.initialize(to: keys)
valuesPointer.initialize(to: values)
let options = CFDictionaryCreate(kCFAllocatorDefault, keysPointer, valuesPointer, keys.count, nil, nil)
let width = cgimage!.width
let height = cgimage!.height
var pxbuffer: CVPixelBuffer?
var status = CVPixelBufferCreate(kCFAllocatorDefault, width, height,
kCVPixelFormatType_32ARGB, options, &pxbuffer)
debugPrint("status = \(status)")
status = CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
let bufferAddress = CVPixelBufferGetBaseAddress(pxbuffer!);
debugPrint("pxbuffer.memory = \(pxbuffer)")
let rgbColorSpace = CGColorSpaceCreateDeviceRGB();
let bytesperrow = CVPixelBufferGetBytesPerRow(pxbuffer!)
let context = CGContext(data: bufferAddress,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: bytesperrow,
space: rgbColorSpace,
bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue);
context?.draw(cgimage!, in: CGRect(x:0, y:0, width:CGFloat(width), height:CGFloat(height)));
status = CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
return pxbuffer!;
}
func convertCIImageToCGImage(inputImage: CIImage) -> CGImage!{
let context = CIContext(options: nil)
return context.createCGImage(inputImage, from: inputImage.extent)
}
@haikieu
Copy link

haikieu commented Nov 16, 2018

What type is rtmpStream?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment