瀏覽代碼

Add MediaInfo to movies and generate action

Gildas Chabot 4 年之前
父節點
當前提交
be9c16ecce
共有 4 個文件被更改,包括 100 次插入8 次删除
  1. 50 0
      ffmpeg/ffmpeg.go
  2. 18 0
      movies.go
  3. 24 8
      pages/pages.go
  4. 8 0
      templates/movie.html

+ 50 - 0
ffmpeg/ffmpeg.go

@@ -0,0 +1,50 @@
1
+package ffmpeg
2
+
3
+import (
4
+	"fmt"
5
+	"os/exec"
6
+	"strings"
7
+)
8
+
9
+const (
10
+	inputFileIdentifier = "INPUT_VIDEO_FILE"
11
+)
12
+
13
+var (
14
+	Debug = true
15
+)
16
+
17
+func MediaInfo(path string) (string, error) {
18
+	out, err := execCommand(
19
+		fmt.Sprintf("-i %s", inputFileIdentifier),
20
+		path)
21
+	if err.Error() == "exit status 1" && strings.HasSuffix(out, "At least one output file must be specified") {
22
+		err = nil
23
+	}
24
+	return out, err
25
+}
26
+
27
+func execCommand(cmdStr, path string) (string, error) {
28
+	cmdSplit := strings.Split(cmdStr, " ")
29
+	for i, s := range cmdSplit {
30
+		if s == inputFileIdentifier {
31
+			cmdSplit[i] = path
32
+		}
33
+	}
34
+
35
+	cmd := exec.Command("ffmpeg", cmdSplit...)
36
+
37
+	if Debug {
38
+		fmt.Println("Executing:", cmd)
39
+	}
40
+	out, err := cmd.CombinedOutput()
41
+	if err != nil {
42
+		fmt.Printf("Error: %#v\n", err.Error())
43
+		return strings.TrimSuffix(string(out), "\n"), err
44
+	}
45
+	if Debug {
46
+		fmt.Printf("Output: %s\n", string(out))
47
+	}
48
+
49
+	return strings.TrimSuffix(string(out), "\n"), err
50
+}

+ 18 - 0
movies.go

@@ -2,8 +2,11 @@ package movies
2 2
 
3 3
 import (
4 4
 	"encoding/json"
5
+	"fmt"
5 6
 	"strconv"
6 7
 	"strings"
8
+
9
+	"gogs.gildas.ch/gildas/movies/ffmpeg"
7 10
 )
8 11
 
9 12
 type Movie struct {
@@ -18,6 +21,7 @@ type Movie struct {
18 21
 
19 22
 	Files     []string
20 23
 	MovieFile string
24
+	MediaInfo string
21 25
 	Subtitles string
22 26
 
23 27
 	OMDB OMDBMovie
@@ -127,3 +131,17 @@ func (m *Movie) FillFromOMDB() error {
127 131
 
128 132
 	return nil
129 133
 }
134
+
135
+func (m *Movie) GenerateMediaInfo() error {
136
+	if m.MovieFile == "" {
137
+		return fmt.Errorf("no movie file set")
138
+	}
139
+
140
+	mediaInfo, err := ffmpeg.MediaInfo(m.MovieFile)
141
+	if err != nil {
142
+		return fmt.Errorf("error generating media info from %q: %w", m.MovieFile, err)
143
+	}
144
+
145
+	m.MediaInfo = mediaInfo
146
+	return nil
147
+}

+ 24 - 8
pages/pages.go

@@ -83,12 +83,14 @@ func Home(c *movies.Collection) http.HandlerFunc {
83 83
 			}
84 84
 		}
85 85
 
86
-		t.Execute(w, map[string]interface{}{
86
+		if err := t.Execute(w, map[string]interface{}{
87 87
 			"Collection": c,
88 88
 			"IMDBID":     r.URL.Query().Get("imdb_id"),
89 89
 			"OMDBString": omdbString,
90 90
 			"Errors":     errs,
91
-		})
91
+		}); err != nil {
92
+			fmt.Println(err)
93
+		}
92 94
 	})
93 95
 }
94 96
 
@@ -135,6 +137,14 @@ func Movie(c *movies.Collection) http.HandlerFunc {
135 137
 				fmt.Println("Update with", m)
136 138
 				c.Update(m)
137 139
 			}
140
+
141
+			if r.FormValue("generate_mediainfo") != "" {
142
+				if err := m.GenerateMediaInfo(); err != nil {
143
+					errs = append(errs, err)
144
+				} else {
145
+					c.Update(m)
146
+				}
147
+			}
138 148
 		}
139 149
 
140 150
 		fileQuery := r.URL.Query().Get("file_query")
@@ -148,14 +158,16 @@ func Movie(c *movies.Collection) http.HandlerFunc {
148 158
 			errs = append(errs, err)
149 159
 		}
150 160
 
151
-		t.Execute(w, map[string]interface{}{
161
+		if err := t.Execute(w, map[string]interface{}{
152 162
 			"Movie":       m,
153 163
 			"MovieJSON":   string(b),
154 164
 			"Files":       strings.Join(m.Files, "\n"),
155 165
 			"FileQuery":   fileQuery,
156 166
 			"FileResults": fileResults,
157 167
 			"Errors":      errs,
158
-		})
168
+		}); err != nil {
169
+			fmt.Println(err)
170
+		}
159 171
 	})
160 172
 }
161 173
 
@@ -206,7 +218,7 @@ func List(c *movies.Collection) http.HandlerFunc {
206 218
 			}
207 219
 		}
208 220
 
209
-		t.Execute(w, map[string]interface{}{
221
+		if err := t.Execute(w, map[string]interface{}{
210 222
 			"List": l,
211 223
 			"Description": template.HTML(
212 224
 				blackfriday.Run(
@@ -215,7 +227,9 @@ func List(c *movies.Collection) http.HandlerFunc {
215 227
 			"Movies":   ms,
216 228
 			"ListJSON": string(b),
217 229
 			"Errors":   errs,
218
-		})
230
+		}); err != nil {
231
+			fmt.Println(err)
232
+		}
219 233
 	})
220 234
 }
221 235
 
@@ -244,10 +258,12 @@ func Files(c *movies.Collection) http.HandlerFunc {
244 258
 			}
245 259
 		}
246 260
 
247
-		t.Execute(w, map[string]interface{}{
261
+		if err := t.Execute(w, map[string]interface{}{
248 262
 			"Files":  c.AllFiles(),
249 263
 			"Errors": errs,
250
-		})
264
+		}); err != nil {
265
+			fmt.Println(err)
266
+		}
251 267
 	})
252 268
 }
253 269
 

+ 8 - 0
templates/movie.html

@@ -18,12 +18,20 @@
18 18
             <div>{{ .Movie.Director }}</div>
19 19
         </div>
20 20
 
21
+        <p>Movie file: <a href="/files/{{ .Movie.MovieFile }}">{{ .Movie.MovieFile }}</a></p>
22
+
23
+        <pre>{{ .Movie.MediaInfo }}</pre>
24
+
21 25
         <ul class="file-list">
22 26
             {{ range $f := .Movie.Files }}
23 27
             <li><a href="/files/{{ $f }}">{{ $f }}</a></li>
24 28
             {{ end }}
25 29
         </ul>
26 30
 
31
+        <div>
32
+            <form method="post"><input type="submit" name="generate_mediainfo" value="Generate MediaInfo" /></form>
33
+        </div>
34
+
27 35
         <div>
28 36
             <form method="post">
29 37
                 <p>Update file list: <input type="submit" /><br />