jafea7-ctbrec-v5.3.2-based/common/src/main/java/ctbrec/Recording.java

259 lines
7.6 KiB
Java

package ctbrec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import com.iheartradio.m3u8.Encoding;
import com.iheartradio.m3u8.Format;
import com.iheartradio.m3u8.ParseException;
import com.iheartradio.m3u8.ParsingMode;
import com.iheartradio.m3u8.PlaylistException;
import com.iheartradio.m3u8.PlaylistParser;
import com.iheartradio.m3u8.data.MediaPlaylist;
import com.iheartradio.m3u8.data.Playlist;
import com.iheartradio.m3u8.data.TrackData;
import ctbrec.event.EventBusHolder;
import ctbrec.event.RecordingStateChangedEvent;
import ctbrec.recorder.download.Download;
public class Recording {
private Model model;
private transient Download download;
private Instant startDate;
private String path;
private State status = State.UNKNOWN;
private int progress = -1;
private long sizeInByte = -1;
private String metaDataFile;
public static enum State {
RECORDING("recording"),
STOPPED("stopped"),
GENERATING_PLAYLIST("generating playlist"),
POST_PROCESSING("post-processing"),
FINISHED("finished"),
DOWNLOADING("downloading"),
DELETING("deleting"),
DELETED("deleted"),
UNKNOWN("unknown"),
WAITING("waiting"),
FAILED("failed");
private String desc;
State(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return desc;
}
}
public Recording() {}
// public Recording(String path) throws ParseException {
// this.path = path;
// this.modelName = path.substring(0, path.indexOf("/"));
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm");
// Date date = sdf.parse(path.substring(path.indexOf('/')+1));
// startDate = Instant.ofEpochMilli(date.getTime());
// }
public Instant getStartDate() {
return startDate;
}
public void setStartDate(Instant startDate) {
this.startDate = startDate;
}
public State getStatus() {
return status;
}
public void setStatus(State status) {
this.status = status;
}
public void setStatusWithEvent(State status, boolean fireEvent) {
setStatus(status);
fireStatusEvent(status);
}
public int getProgress() {
return this.progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public File getAbsoluteFile() {
String recordingsDir = Config.getInstance().getSettings().recordingsDir;
File recordingsFile = new File(recordingsDir, getPath());
return recordingsFile;
}
public long getSizeInByte() {
if (sizeInByte == -1 || getStatus() == State.RECORDING) {
this.sizeInByte = getSize();
}
return sizeInByte;
}
public void setSizeInByte(long sizeInByte) {
this.sizeInByte = sizeInByte;
}
public void postprocess() {
getDownload().postprocess(this);
}
private void fireStatusEvent(State status) {
RecordingStateChangedEvent evt = new RecordingStateChangedEvent(getDownload().getTarget(), status, getModel(), getStartDate());
EventBusHolder.BUS.post(evt);
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
public Download getDownload() {
return download;
}
public void setDownload(Download download) {
this.download = download;
}
public String getMetaDataFile() {
return metaDataFile;
}
public void setMetaDataFile(String metaDataFile) {
this.metaDataFile = metaDataFile;
}
public Duration getLength() throws IOException, ParseException, PlaylistException {
// check, if the recording exists
File rec = new File(Config.getInstance().getSettings().recordingsDir, getPath());
if (!rec.exists()) {
return Duration.ofSeconds(0);
}
// check, if the recording has data at all
long size = getSizeInByte();
if (size == 0) {
return Duration.ofSeconds(0);
}
// determine the length
if (getPath().endsWith(".ts")) {
return Duration.ofSeconds((long) MpegUtil.getFileDuration(rec));
} else if (rec.isDirectory()) {
File playlist = new File(rec, "playlist.m3u8");
if (playlist.exists()) {
return Duration.ofSeconds((long) getPlaylistLength(playlist));
}
}
return Duration.ofSeconds(0);
}
private double getPlaylistLength(File playlist) throws IOException, ParseException, PlaylistException {
if (playlist.exists()) {
PlaylistParser playlistParser = new PlaylistParser(new FileInputStream(playlist), Format.EXT_M3U, Encoding.UTF_8, ParsingMode.LENIENT);
Playlist m3u = playlistParser.parse();
MediaPlaylist mediaPlaylist = m3u.getMediaPlaylist();
double length = 0;
for (TrackData trackData : mediaPlaylist.getTracks()) {
length += trackData.getTrackInfo().duration;
}
return length;
} else {
throw new FileNotFoundException(playlist.getAbsolutePath() + " does not exist");
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getModel() == null) ? 0 : getModel().hashCode());
result = prime * result + ((getPath() == null) ? 0 : getPath().hashCode());
result = prime * result + ((getStartDate() == null) ? 0 : getStartDate().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if(!(obj instanceof Recording)) {
return false;
}
Recording other = (Recording) obj;
if (getModel() == null) {
if (other.getModel() != null)
return false;
} else if (!getModel().equals(other.getModel()))
return false;
if (getPath() == null) {
if (other.getPath() != null)
return false;
} else if (!getPath().equals(other.getPath()))
return false;
if (getStartDate() == null) {
if (other.getStartDate() != null)
return false;
} else if (!getStartDate().equals(other.getStartDate()))
return false;
return true;
}
@Override
public String toString() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(Config.RECORDING_DATE_FORMAT);
LocalDateTime localStartDate = LocalDateTime.ofInstant(getStartDate(), ZoneId.systemDefault());
return getModel().getSanitizedNamed() + '_' + formatter.format(localStartDate);
}
private long getSize() {
File rec = new File(Config.getInstance().getSettings().recordingsDir, getPath());
if(rec.isDirectory()) {
long size = 0;
File[] files = rec.listFiles();
for (File file : files) {
size += file.length();
}
return size;
} else {
return rec.length();
}
}
}