restful.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package record
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "os"
  6. "path/filepath"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "go.uber.org/zap"
  11. . "m7s.live/engine/v4"
  12. "m7s.live/engine/v4/util"
  13. )
  14. func (conf *RecordConfig) API_list(w http.ResponseWriter, r *http.Request) {
  15. query := r.URL.Query()
  16. t := query.Get("type")
  17. var files []*VideoFileInfo
  18. var err error
  19. recorder := conf.getRecorderConfigByType(t)
  20. if recorder == nil {
  21. for _, t = range []string{"flv", "mp4", "fmp4", "hls", "raw", "raw_audio"} {
  22. recorder = conf.getRecorderConfigByType(t)
  23. var fs []*VideoFileInfo
  24. if fs, err = recorder.Tree(recorder.Path, 0); err == nil {
  25. files = append(files, fs...)
  26. }
  27. }
  28. } else {
  29. files, err = recorder.Tree(recorder.Path, 0)
  30. }
  31. if err == nil {
  32. var bytes []byte
  33. if bytes, err = json.Marshal(files); err == nil {
  34. w.Write(bytes)
  35. }
  36. }
  37. if err != nil {
  38. http.Error(w, err.Error(), http.StatusInternalServerError)
  39. }
  40. }
  41. func (conf *RecordConfig) API_start(w http.ResponseWriter, r *http.Request) {
  42. query := r.URL.Query()
  43. streamPath := query.Get("streamPath")
  44. fileName := query.Get("fileName")
  45. fragment := query.Get("fragment")
  46. if streamPath == "" {
  47. http.Error(w, "no streamPath", http.StatusBadRequest)
  48. return
  49. }
  50. t := query.Get("type")
  51. var id string
  52. var err error
  53. var irecorder IRecorder
  54. switch t {
  55. case "":
  56. t = "flv"
  57. fallthrough
  58. case "flv":
  59. irecorder = NewFLVRecorder()
  60. case "mp4":
  61. irecorder = NewMP4Recorder()
  62. case "fmp4":
  63. irecorder = NewFMP4Recorder()
  64. case "hls":
  65. irecorder = NewHLSRecorder()
  66. case "raw":
  67. irecorder = NewRawRecorder()
  68. case "raw_audio":
  69. irecorder = NewRawAudioRecorder()
  70. default:
  71. http.Error(w, "type not supported", http.StatusBadRequest)
  72. return
  73. }
  74. recorder := irecorder.GetRecorder()
  75. if fragment != "" {
  76. if f, err := time.ParseDuration(fragment); err == nil {
  77. recorder.Fragment = f
  78. }
  79. }
  80. recorder.FileName = fileName
  81. recorder.append = query.Get("append") != ""
  82. err = irecorder.Start(streamPath)
  83. id = recorder.ID
  84. if err != nil {
  85. util.ReturnError(util.APIErrorInternal, err.Error(), w, r)
  86. return
  87. }
  88. util.ReturnError(util.APIErrorNone, id, w, r)
  89. }
  90. func (conf *RecordConfig) API_list_recording(w http.ResponseWriter, r *http.Request) {
  91. util.ReturnFetchValue(func() (recordings []any) {
  92. conf.recordings.Range(func(key, value any) bool {
  93. recordings = append(recordings, value)
  94. return true
  95. })
  96. return
  97. }, w, r)
  98. }
  99. func (conf *RecordConfig) API_stop(w http.ResponseWriter, r *http.Request) {
  100. if recorder, ok := conf.recordings.Load(r.URL.Query().Get("id")); ok {
  101. recorder.(ISubscriber).Stop(zap.String("reason", "api"))
  102. util.ReturnOK(w, r)
  103. return
  104. }
  105. util.ReturnError(util.APIErrorNotFound, "no such recorder", w, r)
  106. }
  107. func (conf *RecordConfig) API_recordfile_delete(w http.ResponseWriter, r *http.Request) {
  108. query := r.URL.Query()
  109. path := query.Get("path")
  110. err := os.Remove(path)
  111. if err != nil {
  112. plugin.Error("修改文件时出错", zap.Error(err))
  113. util.ReturnError(1, "删除文件时出错", w, r)
  114. return
  115. }
  116. util.ReturnOK(w, r)
  117. }
  118. func (conf *RecordConfig) API_recordfile_modify(w http.ResponseWriter, r *http.Request) {
  119. query := r.URL.Query()
  120. path := query.Get("path")
  121. newName := query.Get("newName")
  122. dirPath := filepath.Dir(path)
  123. err := os.Rename(path, dirPath+"/"+newName)
  124. if err != nil {
  125. plugin.Error("修改文件时出错", zap.Error(err))
  126. util.ReturnError(1, "修改文件时出错", w, r)
  127. return
  128. }
  129. util.ReturnOK(w, r)
  130. }
  131. func (conf *RecordConfig) API_list_page(w http.ResponseWriter, r *http.Request) {
  132. query := r.URL.Query()
  133. t := query.Get("type")
  134. pageSize := query.Get("pageSize")
  135. pageNum := query.Get("pageNum")
  136. streamPath := query.Get("streamPath") //搜索条件
  137. var files []*VideoFileInfo
  138. var outFiles []*VideoFileInfo
  139. var err error
  140. var totalPageCount int = 1
  141. recorder := conf.getRecorderConfigByType(t)
  142. if recorder == nil {
  143. for _, t = range []string{"flv", "mp4", "fmp4", "hls", "raw", "raw_audio"} {
  144. recorder = conf.getRecorderConfigByType(t)
  145. var fs []*VideoFileInfo
  146. if fs, err = recorder.Tree(recorder.Path, 0); err == nil {
  147. files = append(files, fs...)
  148. }
  149. }
  150. } else {
  151. files, err = recorder.Tree(recorder.Path, 0)
  152. }
  153. if streamPath != "" {
  154. for _, file := range files {
  155. if strings.Contains(file.Path, streamPath) {
  156. outFiles = append(outFiles, file)
  157. }
  158. }
  159. } else {
  160. outFiles = files
  161. }
  162. totalCount := len(outFiles) //总条数
  163. if pageSize != "" && pageNum != "" {
  164. pageSizeInt, err := strconv.Atoi(pageSize)
  165. if err != nil {
  166. http.Error(w, "pageSize parameter error", http.StatusBadRequest)
  167. return
  168. }
  169. pageNumInt, err := strconv.Atoi(pageNum)
  170. if err != nil {
  171. http.Error(w, "pageNum parameter error", http.StatusBadRequest)
  172. return
  173. }
  174. if pageSizeInt > 0 {
  175. if pageNumInt > 0 {
  176. totalPageCount = (totalCount / pageSizeInt) + 1 //总页数
  177. remainCount := totalCount % pageSizeInt //分页后剩余条数
  178. if remainCount == 0 && totalPageCount != 1 {
  179. totalPageCount = totalCount / pageSizeInt
  180. }
  181. if pageNumInt > totalPageCount {
  182. http.Error(w, "pageSize parameter error", http.StatusBadRequest)
  183. return
  184. }
  185. startIndex := (pageNumInt - 1) * pageSizeInt //开始索引
  186. endIndex := startIndex + pageSizeInt
  187. if endIndex > totalCount {
  188. endIndex = totalCount
  189. }
  190. outFiles = outFiles[startIndex:endIndex]
  191. } else {
  192. http.Error(w, "pageNum parameter error", http.StatusBadRequest)
  193. return
  194. }
  195. }
  196. }
  197. if err == nil {
  198. //var bytes []byte
  199. //if bytes, err = json.Marshal(&struct {
  200. // Files []*VideoFileInfo
  201. // TotalCount int
  202. // TotalPageCount int
  203. //}{
  204. // Files: outFiles,
  205. // TotalCount: totalCount,
  206. // TotalPageCount: totalPageCount,
  207. //}); err == nil {
  208. // w.Write(bytes)
  209. //}
  210. util.ReturnValue(&struct {
  211. Files []*VideoFileInfo `json:"files"`
  212. TotalCount int `json:"totalCount"`
  213. TotalPageCount int `json:"totalPageCount"`
  214. }{
  215. Files: outFiles,
  216. TotalCount: totalCount,
  217. TotalPageCount: totalPageCount,
  218. }, w, r)
  219. }
  220. if err != nil {
  221. http.Error(w, err.Error(), http.StatusInternalServerError)
  222. }
  223. }
  224. func (conf *RecordConfig) API_list_recording_page(w http.ResponseWriter, r *http.Request) {
  225. util.ReturnFetchValue(func() (outdata any) {
  226. var recordings []any
  227. conf.recordings.Range(func(key, value any) bool {
  228. recordings = append(recordings, value)
  229. return true
  230. })
  231. query := r.URL.Query()
  232. pageSize := query.Get("pageSize")
  233. pageNum := query.Get("pageNum")
  234. ID := query.Get("ID") //搜索条件
  235. var outRecordings []any
  236. var totalPageCount int = 1
  237. if ID != "" {
  238. for _, record := range recordings {
  239. if strings.Contains(record.(IRecorder).GetRecorder().ID, ID) {
  240. outRecordings = append(outRecordings, record)
  241. }
  242. }
  243. } else {
  244. outRecordings = recordings
  245. }
  246. totalCount := len(outRecordings) //总条数
  247. if pageSize != "" && pageNum != "" {
  248. pageSizeInt, err := strconv.Atoi(pageSize)
  249. if err != nil {
  250. http.Error(w, "pageSize parameter error", http.StatusBadRequest)
  251. return
  252. }
  253. pageNumInt, err := strconv.Atoi(pageNum)
  254. if err != nil {
  255. http.Error(w, "pageNum parameter error", http.StatusBadRequest)
  256. return
  257. }
  258. if pageSizeInt > 0 {
  259. if pageNumInt > 0 {
  260. totalPageCount = (totalCount / pageSizeInt) + 1 //总页数
  261. remainCount := totalCount % pageSizeInt //分页后剩余条数
  262. if remainCount == 0 && totalPageCount != 1 {
  263. totalPageCount = totalCount / pageSizeInt
  264. }
  265. if pageNumInt > totalPageCount {
  266. http.Error(w, "pageSize parameter error", http.StatusBadRequest)
  267. return
  268. }
  269. startIndex := (pageNumInt - 1) * pageSizeInt //开始索引
  270. endIndex := startIndex + pageSizeInt
  271. if endIndex > totalCount {
  272. endIndex = totalCount
  273. }
  274. outRecordings = outRecordings[startIndex:endIndex]
  275. } else {
  276. http.Error(w, "pageNum parameter error", http.StatusBadRequest)
  277. return
  278. }
  279. }
  280. }
  281. outdata = &struct {
  282. Files []any `json:"files"`
  283. TotalCount int `json:"totalCount"`
  284. TotalPageCount int `json:"totalPageCount"`
  285. }{
  286. Files: outRecordings,
  287. TotalCount: totalCount,
  288. TotalPageCount: totalPageCount,
  289. }
  290. return
  291. }, w, r)
  292. }