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"
"errors"
"log"
"msw-open-music/pkg/database"
"net/http"
"os"
"os/exec"
@@ -85,7 +86,7 @@ type PrepareFileStreamDirectRequest struct {
}
type PrepareFileStreamDirectResponse struct {
Filesize int64 `json:"filesize"`
File *database.File `json:"file"`
}
// /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
exists := api.Tmpfs.Exits(objPath)
if exists {
fileInfo, err := os.Stat(objPath)
if !exists {
// 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 {
api.HandleError(w, r, err)
return
}
prepareFileStreamDirectResponse := &PrepareFileStreamDirectResponse{
Filesize: fileInfo.Size(),
}
json.NewEncoder(w).Encode(prepareFileStreamDirectResponse)
return
}
// 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 {
api.HandleError(w, r, err)
return
}
api.Tmpfs.Record(objPath)
api.Tmpfs.Unlock(objPath)
api.Tmpfs.Record(objPath)
api.Tmpfs.Unlock(objPath)
}
fileInfo, err := os.Stat(objPath)
if err != nil {
api.HandleError(w, r, err)
return
}
file.Filesize = fileInfo.Size()
prepareFileStreamDirectResponse := &PrepareFileStreamDirectResponse{
Filesize: fileInfo.Size(),
File: file,
}
json.NewEncoder(w).Encode(prepareFileStreamDirectResponse)
}

View File

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