goffmpeg/examples/stream-reader/main.go

172 lines
4.2 KiB
Go

package main
import (
"fmt"
"io"
"log"
"os"
"git.kingecg.top/kingecg/goffmpeg/pkg/ffmpeg"
"git.kingecg.top/kingecg/goffmpeg/pkg/ffmpeg/stream"
)
// Example 1: Read media info from a URL (local file or network stream)
func exampleReadMediaInfo(inputURL string) {
fmt.Printf("\n=== Example 1: Reading Media Info ===\n")
sr, err := stream.NewStreamReader(stream.TranscodeOptions{
InputURL: inputURL,
})
if err != nil {
log.Printf("Failed to create stream reader: %v", err)
return
}
defer sr.Close()
info, err := sr.MediaInfo()
if err != nil {
log.Printf("Failed to get media info: %v", err)
return
}
fmt.Printf("Media Info:\n")
fmt.Printf(" Duration: %v\n", info.Duration)
fmt.Printf(" Start Time: %v\n", info.StartTime)
fmt.Printf(" Bit Rate: %d bps\n", info.BitRate)
fmt.Printf(" Streams: %d\n", len(info.Streams))
for i, s := range info.Streams {
fmt.Printf(" Stream %d:\n", i)
fmt.Printf(" Type: %v\n", s.Type)
fmt.Printf(" Codec: %s (%s)\n", s.CodecName, s.CodecLongName)
if s.Type == ffmpeg.CodecTypeVideo {
fmt.Printf(" Resolution: %dx%d\n", s.Width, s.Height)
fmt.Printf(" Pixel Format: %s\n", s.PixelFormat)
} else if s.Type == ffmpeg.CodecTypeAudio {
fmt.Printf(" Sample Rate: %d\n", s.SampleRate)
fmt.Printf(" Channels: %d\n", s.Channels)
fmt.Printf(" Channel Layout: %s\n", s.ChannelLayout)
}
}
}
// Example 2: Stream copy (remux) from input to output
func exampleStreamCopy(inputURL, outputURL string) {
fmt.Printf("\n=== Example 2: Stream Copy (Remux) ===\n")
sr, err := stream.NewStreamReader(stream.TranscodeOptions{
InputURL: inputURL,
})
if err != nil {
log.Printf("Failed to create stream reader: %v", err)
return
}
defer sr.Close()
// Create output file
outFile, err := os.Create(outputURL)
if err != nil {
log.Printf("Failed to create output file: %v", err)
return
}
defer outFile.Close()
// Read data from stream reader and write to output
fmt.Printf("Copying stream from %s to %s...\n", inputURL, outputURL)
buf := make([]byte, 32768)
written := 0
for {
n, err := sr.Read(buf)
if n > 0 {
outFile.Write(buf[:n])
written += n
fmt.Printf("\rWritten: %d bytes", written)
}
if err != nil {
if err == io.EOF {
fmt.Println("\nStream copy completed!")
break
}
log.Printf("\nError reading stream: %v", err)
break
}
}
}
// Example 3: Read from io.Reader
func exampleReadFromReader(inputURL string) {
fmt.Printf("\n=== Example 3: Read from io.Reader ===\n")
// Open input file as io.Reader
inFile, err := os.Open(inputURL)
if err != nil {
log.Printf("Failed to open input file: %v", err)
return
}
defer inFile.Close()
sr, err := stream.NewStreamReader(stream.TranscodeOptions{
InputIO: inFile,
})
if err != nil {
log.Printf("Failed to create stream reader: %v", err)
return
}
defer sr.Close()
info, err := sr.MediaInfo()
if err != nil {
log.Printf("Failed to get media info: %v", err)
return
}
fmt.Printf("Media info from io.Reader:\n")
fmt.Printf(" Duration: %v\n", info.Duration)
fmt.Printf(" Streams: %d\n", len(info.Streams))
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: stream-reader <command> [args]")
fmt.Println("\nCommands:")
fmt.Println(" info <input> - Read and display media info")
fmt.Println(" copy <input> <output> - Copy/remux stream")
fmt.Println(" reader <input> - Read from io.Reader")
fmt.Println("\nExamples:")
fmt.Println(" stream-reader info /path/to/video.mp4")
fmt.Println(" stream-reader copy input.mp4 output.flv")
fmt.Println(" stream-reader reader /path/to/video.mp4")
os.Exit(1)
}
command := os.Args[1]
switch command {
case "info":
if len(os.Args) < 3 {
fmt.Println("Usage: stream-reader info <input>")
os.Exit(1)
}
exampleReadMediaInfo(os.Args[2])
case "copy":
if len(os.Args) < 4 {
fmt.Println("Usage: stream-reader copy <input> <output>")
os.Exit(1)
}
exampleStreamCopy(os.Args[2], os.Args[3])
case "reader":
if len(os.Args) < 3 {
fmt.Println("Usage: stream-reader reader <input>")
os.Exit(1)
}
exampleReadFromReader(os.Args[2])
default:
fmt.Printf("Unknown command: %s\n", command)
os.Exit(1)
}
}