Fix: play another file while current file is preparing

This commit is contained in:
2021-12-14 01:30:28 +08:00
parent 47b178ac90
commit d59e40c6fa
2 changed files with 32 additions and 35 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"log" "log"
"msw-open-music/pkg/database"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@@ -85,7 +86,7 @@ type PrepareFileStreamDirectRequest struct {
} }
type PrepareFileStreamDirectResponse struct { type PrepareFileStreamDirectResponse struct {
Filesize int64 `json:"filesize"` File *database.File `json:"file"`
} }
// /prepare_file_stream_direct?id=1&config=ffmpeg_config_name // /prepare_file_stream_direct?id=1&config=ffmpeg_config_name
@@ -130,44 +131,37 @@ func (api *API) HandlePrepareFileStreamDirect(w http.ResponseWriter, r *http.Req
// check obj file exists // check obj file exists
exists := api.Tmpfs.Exits(objPath) exists := api.Tmpfs.Exits(objPath)
if exists { if !exists {
fileInfo, err := os.Stat(objPath) // lock the object
api.Tmpfs.Lock(objPath)
args := strings.Split(ffmpegConfig.Args, " ")
startArgs := []string{"-threads", strconv.FormatInt(api.APIConfig.FfmpegThreads, 10), "-i", srcPath}
endArgs := []string{"-vn", "-y", objPath}
ffmpegArgs := append(startArgs, args...)
ffmpegArgs = append(ffmpegArgs, endArgs...)
cmd := exec.Command("ffmpeg", ffmpegArgs...)
err = cmd.Run()
if err != nil { if err != nil {
api.HandleError(w, r, err) api.HandleError(w, r, err)
return return
} }
prepareFileStreamDirectResponse := &PrepareFileStreamDirectResponse{
Filesize: fileInfo.Size(),
}
json.NewEncoder(w).Encode(prepareFileStreamDirectResponse)
return
}
// lock the object
api.Tmpfs.Lock(objPath)
args := strings.Split(ffmpegConfig.Args, " ") api.Tmpfs.Record(objPath)
startArgs := []string{"-threads", strconv.FormatInt(api.APIConfig.FfmpegThreads, 10), "-i", srcPath} api.Tmpfs.Unlock(objPath)
endArgs := []string{"-vn", "-y", objPath}
ffmpegArgs := append(startArgs, args...)
ffmpegArgs = append(ffmpegArgs, endArgs...)
cmd := exec.Command("ffmpeg", ffmpegArgs...)
err = cmd.Run()
if err != nil {
api.HandleError(w, r, err)
return
}
api.Tmpfs.Record(objPath) }
api.Tmpfs.Unlock(objPath)
fileInfo, err := os.Stat(objPath) fileInfo, err := os.Stat(objPath)
if err != nil { if err != nil {
api.HandleError(w, r, err) api.HandleError(w, r, err)
return return
} }
file.Filesize = fileInfo.Size()
prepareFileStreamDirectResponse := &PrepareFileStreamDirectResponse{ prepareFileStreamDirectResponse := &PrepareFileStreamDirectResponse{
Filesize: fileInfo.Size(), File: file,
} }
json.NewEncoder(w).Encode(prepareFileStreamDirectResponse) json.NewEncoder(w).Encode(prepareFileStreamDirectResponse)
} }

View File

@@ -12,10 +12,12 @@ function AudioPlayer(props) {
const [loop, setLoop] = useState(true); const [loop, setLoop] = useState(true);
const [raw, setRaw] = useState(false); const [raw, setRaw] = useState(false);
const [prepare, setPrepare] = useState(false); const [prepare, setPrepare] = useState(false);
const [selectedFfmpegConfig, setSelectedFfmpegConfig] = useState({}); const [selectedFfmpegConfig, setSelectedFfmpegConfig] = useState({
name: "",
args: "",
});
const [playingURL, setPlayingURL] = useState(""); const [playingURL, setPlayingURL] = useState("");
const [isPreparing, setIsPreparing] = useState(false); const [isPreparing, setIsPreparing] = useState(false);
const [preparedFilesize, setPreparedFilesize] = useState(null);
useEffect(() => { useEffect(() => {
// no playing file // no playing file
@@ -40,7 +42,12 @@ function AudioPlayer(props) {
}) })
.then((response) => response.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
setPreparedFilesize(data.filesize); if (data.error) {
alert(data.error);
setIsPreparing(false);
return;
}
props.setPlayingFile(data.file);
setIsPreparing(false); setIsPreparing(false);
setPlayingURL( setPlayingURL(
`/api/v1/get_file_stream_direct?id=${props.playingFile.id}&config=${selectedFfmpegConfig.name}` `/api/v1/get_file_stream_direct?id=${props.playingFile.id}&config=${selectedFfmpegConfig.name}`
@@ -79,17 +86,13 @@ function AudioPlayer(props) {
</button> </button>
<button <button
onClick={() => onClick={() => navigate(`/folders/${props.playingFile.folder_id}`)}
navigate(`/folders/${props.playingFile.folder_id}`)
}
> >
{props.playingFile.foldername} {props.playingFile.foldername}
</button> </button>
<button disabled> <button disabled>
{prepare {CalcReadableFilesizeDetail(props.playingFile.filesize)}
? CalcReadableFilesizeDetail(preparedFilesize)
: CalcReadableFilesizeDetail(props.playingFile.filesize)}
</button> </button>
{isPreparing && <button disabled>Preparing...</button>} {isPreparing && <button disabled>Preparing...</button>}