Fix: play another file while current file is preparing
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>}
|
||||||
|
|||||||
Reference in New Issue
Block a user