-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
127 lines (111 loc) · 3.03 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"bytes"
"fmt"
"os"
"os/exec"
"strings"
)
// Function to compute the MD5 hash of a specific stream
func computeStreamMD5(filePath string, streamSpecifier string) (string, error) {
cmd := exec.Command("ffmpeg", "-loglevel", "error", "-i", filePath, "-map", streamSpecifier, "-f", "md5", "-")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return "", err
}
// The output format is "MD5=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
output := strings.TrimSpace(out.String())
if strings.HasPrefix(output, "MD5=") {
return strings.TrimPrefix(output, "MD5="), nil
}
return "", fmt.Errorf("unexpected output: %s", output)
}
// Function to count the number of streams of a particular type in a file
func countStreams(filePath string, streamType string) (int, error) {
cmd := exec.Command("ffprobe", "-loglevel", "error", "-select_streams", streamType, "-show_entries", "stream=index", "-of", "csv=p=0", filePath)
output, err := cmd.Output()
if err != nil {
return 0, err
}
// Count the number of lines in the output, each representing a stream
return len(strings.Split(strings.TrimSpace(string(output)), "\n")), nil
}
// Function to check if two files are identical in terms of their streams
func areFilesIdentical(file1, file2 string) (bool, error) {
// Count the number of video streams
numVideoStreams1, err := countStreams(file1, "v")
if err != nil {
return false, err
}
numVideoStreams2, err := countStreams(file2, "v")
if err != nil {
return false, err
}
// Count the number of audio streams
numAudioStreams1, err := countStreams(file1, "a")
if err != nil {
return false, err
}
numAudioStreams2, err := countStreams(file2, "a")
if err != nil {
return false, err
}
// Compare the number of streams
if numVideoStreams1 != numVideoStreams2 || numAudioStreams1 != numAudioStreams2 {
return false, nil
}
// Compare the video streams
for i := 0; i < numVideoStreams1; i++ {
streamSpecifier := fmt.Sprintf("0:v:%d", i)
hash1, err := computeStreamMD5(file1, streamSpecifier)
if err != nil {
return false, err
}
hash2, err := computeStreamMD5(file2, streamSpecifier)
if err != nil {
return false, err
}
if hash1 != hash2 {
return false, nil
}
}
// Compare the audio streams
for i := 0; i < numAudioStreams1; i++ {
streamSpecifier := fmt.Sprintf("0:a:%d", i)
hash1, err := computeStreamMD5(file1, streamSpecifier)
if err != nil {
return false, err
}
hash2, err := computeStreamMD5(file2, streamSpecifier)
if err != nil {
return false, err
}
if hash1 != hash2 {
return false, nil
}
}
return true, nil
}
func main() {
if len(os.Args) != 3 {
fmt.Println("Usage: mediastreamcmp <file1> <file2>")
return
}
file1 := os.Args[1]
file2 := os.Args[2]
identical, err := areFilesIdentical(file1, file2)
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
return
}
if identical {
fmt.Println("The files are identical in terms of audio and video streams.")
os.Exit(0)
} else {
fmt.Println("The files are not identical.")
os.Exit(2)
}
}