Remove segment mergers
Segment mergers are not needed anymore. Segments get merged during the recording or during the download from the server.
This commit is contained in:
parent
7cc5764461
commit
cda1f25dc0
|
@ -1,94 +0,0 @@
|
||||||
package ctbrec.recorder;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.iheartradio.m3u8.Encoding;
|
|
||||||
import com.iheartradio.m3u8.Format;
|
|
||||||
import com.iheartradio.m3u8.ParseException;
|
|
||||||
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.DevNull;
|
|
||||||
|
|
||||||
public class FFmpegSegmentMerger implements SegmentMerger {
|
|
||||||
private static final transient Logger LOG = LoggerFactory.getLogger(FFmpegSegmentMerger.class);
|
|
||||||
|
|
||||||
private int lastPercentage;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void merge(File recDir, File targetFile) throws IOException, ParseException, PlaylistException {
|
|
||||||
if (targetFile.exists()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File playlistFile = new File(recDir, "playlist.m3u8");
|
|
||||||
if (!playlistFile.exists()) {
|
|
||||||
LOG.warn("Couldn't merge segments. Playlist {} does not exist", playlistFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Runtime rt = Runtime.getRuntime();
|
|
||||||
Process ffmpeg = rt.exec("ffmpeg -y -i - -c:v copy -c:a copy -f mp4 " + targetFile.getCanonicalPath());
|
|
||||||
|
|
||||||
// create threads, which read stdout and stderr of the player process. these are needed,
|
|
||||||
// because otherwise the internal buffer for these streams fill up and block the process
|
|
||||||
Thread std = new Thread(new StreamRedirectThread(ffmpeg.getInputStream(), new DevNull()));
|
|
||||||
std.setName("FFmpeg stdout pipe");
|
|
||||||
std.setDaemon(true);
|
|
||||||
std.start();
|
|
||||||
Thread err = new Thread(new StreamRedirectThread(ffmpeg.getErrorStream(), new DevNull()));
|
|
||||||
err.setName("FFmpeg stderr pipe");
|
|
||||||
err.setDaemon(true);
|
|
||||||
err.start();
|
|
||||||
|
|
||||||
try (FileInputStream fin = new FileInputStream(playlistFile); OutputStream ffmpegStdin = ffmpeg.getOutputStream()) {
|
|
||||||
PlaylistParser parser = new PlaylistParser(fin, Format.EXT_M3U, Encoding.UTF_8);
|
|
||||||
Playlist playlist = parser.parse();
|
|
||||||
MediaPlaylist mediaPlaylist = playlist.getMediaPlaylist();
|
|
||||||
List<TrackData> tracks = mediaPlaylist.getTracks();
|
|
||||||
for (int i = 0; i < tracks.size(); i++) {
|
|
||||||
TrackData trackData = tracks.get(i);
|
|
||||||
File segment = new File(recDir, trackData.getUri());
|
|
||||||
if (segment.exists()) {
|
|
||||||
try (FileInputStream segmentStream = new FileInputStream(segment)) {
|
|
||||||
int length = -1;
|
|
||||||
byte[] b = new byte[1024 * 1024];
|
|
||||||
while ((length = segmentStream.read(b)) >= 0) {
|
|
||||||
ffmpegStdin.write(b, 0, length);
|
|
||||||
}
|
|
||||||
lastPercentage = (int) (i * 100.0 / tracks.size());
|
|
||||||
Thread.sleep(10);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.error("Couldn't append segment {} to merged file {}", segment.getName(), targetFile.getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
int exitCode = ffmpeg.waitFor();
|
|
||||||
if(exitCode != 0) {
|
|
||||||
throw new IOException("FFmpeg exited with code " + exitCode);
|
|
||||||
} else {
|
|
||||||
LOG.debug("FFmpeg finished.");
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
LOG.error("Interrupted while waiting for FFmpeg to finish");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getProgress() {
|
|
||||||
return lastPercentage;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@ package ctbrec.recorder;
|
||||||
|
|
||||||
import static ctbrec.Recording.STATUS.FINISHED;
|
import static ctbrec.Recording.STATUS.FINISHED;
|
||||||
import static ctbrec.Recording.STATUS.GENERATING_PLAYLIST;
|
import static ctbrec.Recording.STATUS.GENERATING_PLAYLIST;
|
||||||
import static ctbrec.Recording.STATUS.MERGING;
|
|
||||||
import static ctbrec.Recording.STATUS.RECORDING;
|
import static ctbrec.Recording.STATUS.RECORDING;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -47,7 +46,6 @@ public class LocalRecorder implements Recorder {
|
||||||
private List<Model> models = Collections.synchronizedList(new ArrayList<>());
|
private List<Model> models = Collections.synchronizedList(new ArrayList<>());
|
||||||
private Map<Model, Download> recordingProcesses = Collections.synchronizedMap(new HashMap<>());
|
private Map<Model, Download> recordingProcesses = Collections.synchronizedMap(new HashMap<>());
|
||||||
private Map<File, PlaylistGenerator> playlistGenerators = new HashMap<>();
|
private Map<File, PlaylistGenerator> playlistGenerators = new HashMap<>();
|
||||||
private Map<File, SegmentMerger> segmentMergers = new HashMap<>();
|
|
||||||
private Config config;
|
private Config config;
|
||||||
private ProcessMonitor processMonitor;
|
private ProcessMonitor processMonitor;
|
||||||
private OnlineMonitor onlineMonitor;
|
private OnlineMonitor onlineMonitor;
|
||||||
|
@ -460,19 +458,13 @@ public class LocalRecorder implements Recorder {
|
||||||
recording.setStatus(GENERATING_PLAYLIST);
|
recording.setStatus(GENERATING_PLAYLIST);
|
||||||
recording.setProgress(playlistGenerator.getProgress());
|
recording.setProgress(playlistGenerator.getProgress());
|
||||||
} else {
|
} else {
|
||||||
SegmentMerger merger = segmentMergers.get(rec);
|
if (Recording.isMergedRecording(rec)) {
|
||||||
if (merger != null) {
|
recording.setStatus(FINISHED);
|
||||||
recording.setStatus(MERGING);
|
|
||||||
recording.setProgress(merger.getProgress());
|
|
||||||
} else {
|
} else {
|
||||||
if (Recording.isMergedRecording(rec)) {
|
if (recording.hasPlaylist()) {
|
||||||
recording.setStatus(FINISHED);
|
recording.setStatus(FINISHED);
|
||||||
} else {
|
} else {
|
||||||
if (recording.hasPlaylist()) {
|
recording.setStatus(RECORDING);
|
||||||
recording.setStatus(FINISHED);
|
|
||||||
} else {
|
|
||||||
recording.setStatus(RECORDING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package ctbrec.recorder;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.iheartradio.m3u8.ParseException;
|
|
||||||
import com.iheartradio.m3u8.PlaylistException;
|
|
||||||
|
|
||||||
|
|
||||||
public interface SegmentMerger {
|
|
||||||
|
|
||||||
|
|
||||||
public void merge(File recDir, File targetFile) throws IOException, ParseException, PlaylistException;
|
|
||||||
|
|
||||||
public int getProgress();
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package ctbrec.recorder;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.iheartradio.m3u8.Encoding;
|
|
||||||
import com.iheartradio.m3u8.Format;
|
|
||||||
import com.iheartradio.m3u8.ParseException;
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
public class SimpleSegmentMerger implements SegmentMerger {
|
|
||||||
private static final transient Logger LOG = LoggerFactory.getLogger(SimpleSegmentMerger.class);
|
|
||||||
|
|
||||||
private int lastPercentage;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void merge(File recDir, File targetFile) throws IOException, ParseException, PlaylistException {
|
|
||||||
if (targetFile.exists()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File playlistFile = new File(recDir, "playlist.m3u8");
|
|
||||||
if(!playlistFile.exists()) {
|
|
||||||
LOG.warn("Couldn't merge segments. Playlist {} does not exist", playlistFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileInputStream fin = new FileInputStream(playlistFile); FileOutputStream fos = new FileOutputStream(targetFile)) {
|
|
||||||
PlaylistParser parser = new PlaylistParser(fin, Format.EXT_M3U, Encoding.UTF_8);
|
|
||||||
Playlist playlist = parser.parse();
|
|
||||||
MediaPlaylist mediaPlaylist = playlist.getMediaPlaylist();
|
|
||||||
List<TrackData> tracks = mediaPlaylist.getTracks();
|
|
||||||
for (int i = 0; i < tracks.size(); i++) {
|
|
||||||
TrackData trackData = tracks.get(i);
|
|
||||||
File segment = new File(recDir, trackData.getUri());
|
|
||||||
if(segment.exists()) {
|
|
||||||
try (FileInputStream segmentStream = new FileInputStream(segment)) {
|
|
||||||
int length = -1;
|
|
||||||
byte[] b = new byte[1024 * 1024];
|
|
||||||
while ((length = segmentStream.read(b)) >= 0) {
|
|
||||||
fos.write(b, 0, length);
|
|
||||||
}
|
|
||||||
lastPercentage = (int) (i * 100.0 / tracks.size());
|
|
||||||
} catch(Exception e) {
|
|
||||||
LOG.error("Couldn't append segment {} to merged file {}", segment.getName(), targetFile.getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getProgress() {
|
|
||||||
return lastPercentage;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue