Skip to content

Instantly share code, notes, and snippets.

@nasifimtiazohi
Last active April 19, 2023 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasifimtiazohi/518092fc60101bf973fbbb0dd475ed02 to your computer and use it in GitHub Desktop.
Save nasifimtiazohi/518092fc60101bf973fbbb0dd475ed02 to your computer and use it in GitHub Desktop.
/*
* MediathekView
* Copyright (C) 2008 W. Xaver
* W.Xaver[at]googlemail.com
* http://zdfmediathk.sourceforge.net/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package mediathek.controller.io.starter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mediathek.daten.DatenDownload;
import mediathek.tool.Log;
public class RuntimeExec {
private static final int INPUT = 1; // Nasif: We can put this as enum
private static final int ERROR = 2;
private String prog;
Thread clearIn;
Thread clearOut;
private Process process = null;
Start s;
private static int procnr = 0; //TH
private Pattern patternFlvstreamer = Pattern.compile("([0-9.]*%)");
private Pattern patternFfmpeg = Pattern.compile("(?<=Duration: )[^,]*");
private Pattern patternZeit = Pattern.compile("(?<=time=)[\\d.]+");
private double totalSecs = 0;
private String zeit, prozent;
public RuntimeExec(Start st) {
s = st;
prog = s.datenDownload.arr[DatenDownload.DOWNLOAD_PROGRAMM_AUFRUF_NR]; // Are we sure this won't go out of index
}
public RuntimeExec(String p) {
prog = p;
}
//===================================
// Public
//===================================
/**
* Download starten
*/
public Process exec() {
try {
process = Runtime.getRuntime().exec(prog);
clearIn = new Thread(new ClearInOut(INPUT, process));
clearOut = new Thread(new ClearInOut(ERROR, process));
clearIn.start();
clearOut.start();
} catch (Exception ex) {
//bescheid geben
if (process == null) {
} // Nasif: this condition is doing nothing
Log.fehlerMeldung(450028932, Log.FEHLER_ART_PROG, "RuntimeExec.exec", ex, "Fehler beim Starten");
}
return process;
}
//===================================
// Private
//===================================
private class ClearInOut implements Runnable {
private int art;
private BufferedReader buff;
private InputStream in;
private Process process;
private int percent = 0;
private int percent_start = -1;
public ClearInOut(int a, Process p) {
art = a;
process = p;
}
@Override
public void run() {
String titel = "";
try {
switch (art) {
case INPUT:
in = process.getInputStream();
// Nasif: why didn't we synchronize this?
titel = "INPUTSTREAM";
break;
case ERROR:
in = process.getErrorStream();
//TH
synchronized (this) {
titel = "ERRORSTREAM [" + (++procnr) + "]";
}
break;
// Nasif: Do we need a default case here?
}
buff = new BufferedReader(new InputStreamReader(in));
String inStr;
while ((inStr = buff.readLine()) != null) {
GetPercentageFromErrorStream(inStr);
Log.playerMeldung(titel + ": " + inStr);
}
} catch (IOException ex) {
// Nasif: shouldn't we do some logging here?
} finally {
try {
buff.close();
} catch (IOException ex) {
// Nasif: shouldn't we do some logging here?
}
}
}
private void GetPercentageFromErrorStream(String input) {
// by: siedlerchr
// für den flvstreamer und rtmpdump
Matcher matcher = patternFlvstreamer.matcher(input);
if (matcher.find()) {
try {
prozent = matcher.group();
prozent = prozent.substring(0, prozent.length() - 1);
double d = Double.parseDouble(prozent);
meldenDouble(d);
} catch (Exception ex) {
s.datenDownload.statusMelden(DatenDownload.PROGRESS_GESTARTET);
Log.fehlerMeldung(912036780, Log.FEHLER_ART_PROG, "RuntimeExec.GetPercentageFromErrorStream-1", input);
}
} else {
// für ffmpeg
// ffmpeg muss dazu mit dem Parameter -i gestartet werden:
// -i %f -acodec copy -vcodec copy -y **
try {
matcher = patternFfmpeg.matcher(input);
if (matcher.find()) {
// Find duration
String dauer = matcher.group();
String[] hms = dauer.split(":");
totalSecs = Integer.parseInt(hms[0]) * 3600
+ Integer.parseInt(hms[1]) * 60
+ Double.parseDouble(hms[2]);
}
matcher = patternZeit.matcher(input);
if (totalSecs > 0 && matcher.find()) {
zeit = matcher.group();
double d = Double.parseDouble(zeit) / totalSecs * 100;
meldenDouble(d);
}
} catch (Exception ex) {
s.datenDownload.statusMelden(DatenDownload.PROGRESS_GESTARTET);
Log.fehlerMeldung(912036780, Log.FEHLER_ART_PROG, "RuntimeExec.GetPercentageFromErrorStream-2", input);
}
}
}
private void meldenDouble(double d) {
// nur ganze Int speichern, und 1000 Schritte
d *= 10;
int pNeu = (int) d;
if (pNeu != percent) {
percent = pNeu;
if (percent_start == -1) {
// für wiedergestartete Downloads
percent_start = percent;
}
if (percent > (percent_start + 5)) {
// sonst macht es noch keinen Sinn
int diffZeit = s.startZeit.diffInSekunden();
int diffProzent = percent - percent_start;
int restProzent = 1000 - percent;
s.restSekunden = (diffZeit * restProzent / diffProzent);
}
s.datenDownload.statusMelden(percent);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment