# Vidio A simple Video I/O library written in Go. This library relies on [FFmpeg](https://www.ffmpeg.org/), and [FFProbe](https://www.ffmpeg.org/) which must be downloaded before usage and added to the system path. All frames are encoded and decoded in 8-bit RGB format. ## Installation ``` go get github.com/AlexEidt/Vidio ``` ## `Video` The `Video` struct stores data about a video file you give it. The code below shows an example of sequentially reading the frames of the given video. ```go type Video struct { filename string // Video Filename width int // Width of Frames height int // Height of Frames depth int // Depth of Frames bitrate int // Bitrate for video encoding frames int // Total number of frames duration float64 // Duration in seconds fps float64 // Frames per second codec string // Codec used to encode video audio_codec string // Codec used for audio encoding pix_fmt string // Pixel format video is stored in framebuffer []byte // Raw frame data pipe *io.ReadCloser // Stdout pipe for ffmpeg process cmd *exec.Cmd // ffmpeg command } ``` ```go video := vidio.NewVideo("input.mp4") for video.Read() { // "frame" stores the video frame as a flattened RGB image frame := video.framebuffer // stored as: RGBRGBRGBRGB... // Video processing here... } ``` ## `Camera` The `Camera` can read from any cameras on the device running Vidio. It takes in the stream index. On most machines the webcam device has index 0. Note that audio retrieval from the microphone is not yet supported. ```go type Camera struct { name string // Camera device name width int // Camera frame width height int // Camera frame height depth int // Camera frame depth fps float64 // Camera frames per second codec string // Camera codec framebuffer []byte // Raw frame data pipe *io.ReadCloser // Stdout pipe for ffmpeg process streaming webcam cmd *exec.Cmd // ffmpeg command } ``` ```go camera := vidio.NewCamera(0) // Get Webcam defer camera.Close() // Stream the webcam for camera.Read() { // "frame" stores the video frame as a flattened RGB image frame := camera.framebuffer // stored as: RGBRGBRGBRGB... // Video processing here... } ``` ## `VideoWriter` The `VideoWriter` is used to write frames to a video file. The only required parameters are the output file name, the width and height of the frames being written, and an `Options` struct. This contains all the desired properties of the new video you want to create. ```go type Options struct { bitrate int // Bitrate loop int // For GIFs only. -1=no loop, 0=loop forever, >0=loop n times delay int // Delay for Final Frame of GIFs. Default -1 (Use same delay as previous frame) macro int // macro size for determining how to resize frames for codecs. Default 16 fps float64 // Frames per second. Default 25 quality float64 // If bitrate not given, use quality instead. Must be between 0 and 1. 0:best, 1:worst codec string // Codec for video. Default libx264 audio string // File path for audio for the video. If no audio, audio=nil. audio_codec string // Codec for audio. Default aac } ``` ```go type VideoWriter struct { filename string // Output filename audio string // Audio filename width int // Frame width height int // Frame height bitrate int // Output video bitrate loop int // Number of times for GIF to loop delay int // Delay of final frame of GIF. Default -1 (same delay as previous frame) macro int // Macroblock size for determining how to resize frames for codecs fps float64 // Frames per second for output video. Default 25 quality float64 // Used if bitrate not given. Default 0.5 codec string // Codec to encode video with. Default libx264 audio_codec string // Codec to encode audio with. Default aac pipe *io.WriteCloser // Stdout pipe of ffmpeg process cmd *exec.Cmd // ffmpeg command } ``` ```go w, h, c := 1920, 1080, 3 options := vidio.Options{} // Will fill in defaults if empty writer := vidio.NewVideoWriter("output.mp4", w, h, &options) defer writer.Close() frame := make([]byte, w*h*c) // Create Frame as RGB Image and modify writer.Write(frame) // Write Frame to video ``` ## Images Vidio provides some convenience functions for reading and writing to images using an array of bytes. Currently, only `png` and `jpeg` formats are supported. ```go // Read png image w, h, img := vidio.Read("input.png") // w - width of image // h - height of image // img - byte array in RGB format. RGBRGBRGBRGB... vidio.Write("output.jpg", w, h, img) ``` ## Examples Copy `input.mp4` to `output.mp4`. Copy the audio from `input.mp4` to `output.mp4` as well. ```go video := vidio.NewVideo("input.mp4") options := vidio.Options{ fps: video.fps, bitrate: video.bitrate, audio: "input.mp4", } writer := vidio.NewVideoWriter("output.mp4", video.width, video.height, &options) defer writer.Close() for video.Read() { writer.Write(video.framebuffer) } ``` Grayscale 1000 frames of webcam stream and store in `output.mp4`. ```go webcam := vidio.NewCamera(0) defer webcam.Close() options := vidio.Options{fps: webcam.fps} writer := vidio.NewVideoWriter("output.mp4", webcam.width, webcam.height, &options) defer writer.Close() count := 0 for webcam.Read() { for i := 0; i < len(webcam.framebuffer); i += 3 { rgb := webcam.framebuffer[i : i+3] r, g, b := int(rgb[0]), int(rgb[1]), int(rgb[2]) gray := uint8((3*r + 4*g + b) / 8) writer.framebuffer[i] = gray writer.framebuffer[i+1] = gray writer.framebuffer[i+2] = gray } writer.Write(webcam.framebuffer) count++ if count > 1000 { break } } ``` Create a gif from a series of `png` files enumerated from 1 to 10 that loops continuously with a final frame delay of 1000 centiseconds. ```go w, h, _ := vidio.Read("1.png") // Get frame dimensions from first image options := vidio.Options{fps: 1, loop: -1, delay: 1000} gif := vidio.NewVideoWriter("output.gif", w, h, &options) defer gif.Close() for i := 1; i <= 10; i++ { _, _, img := vidio.Read(strconv.Itoa(i)+".png") gif.Write(img) } ``` # Acknowledgements * Special thanks to [Zulko](http://zulko.github.io/) and his [blog post](http://zulko.github.io/blog/2013/09/27/read-and-write-video-frames-in-python-using-ffmpeg/) about using FFmpeg to process video. * The [ImageIO-FFMPEG](https://github.com/imageio/imageio-ffmpeg/) project on GitHub.