diff --git a/src/main/java/ctbrec/ui/StreamSourceSelectionDialog.java b/src/main/java/ctbrec/ui/StreamSourceSelectionDialog.java new file mode 100644 index 00000000..73057f16 --- /dev/null +++ b/src/main/java/ctbrec/ui/StreamSourceSelectionDialog.java @@ -0,0 +1,71 @@ +package ctbrec.ui; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.iheartradio.m3u8.data.MasterPlaylist; +import com.iheartradio.m3u8.data.PlaylistData; + +import ctbrec.HttpClient; +import ctbrec.Model; +import ctbrec.recorder.Chaturbate; +import ctbrec.recorder.StreamInfo; +import ctbrec.recorder.download.StreamSource; +import javafx.concurrent.Task; +import javafx.scene.control.ChoiceDialog; + +public class StreamSourceSelectionDialog { + private static final transient Logger LOG = LoggerFactory.getLogger(StreamSourceSelectionDialog.class); + + public static void show(Model model, HttpClient client, Function onSuccess, Function onFail) { + Task> selectStreamSource = new Task>() { + @Override + protected List call() throws Exception { + StreamInfo streamInfo = Chaturbate.getStreamInfo(model, client); + MasterPlaylist masterPlaylist = Chaturbate.getMasterPlaylist(streamInfo, client); + List sources = new ArrayList<>(); + for (PlaylistData playlist : masterPlaylist.getPlaylists()) { + if (playlist.hasStreamInfo()) { + StreamSource src = new StreamSource(); + src.bandwidth = playlist.getStreamInfo().getBandwidth(); + src.height = playlist.getStreamInfo().getResolution().height; + String masterUrl = streamInfo.url; + String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1); + String segmentUri = baseUrl + playlist.getUri(); + src.mediaPlaylistUrl = segmentUri; + LOG.trace("Media playlist {}", src.mediaPlaylistUrl); + sources.add(src); + } + } + return sources; + } + }; + selectStreamSource.setOnSucceeded((e) -> { + List sources; + try { + sources = selectStreamSource.get(); + ChoiceDialog choiceDialog = new ChoiceDialog(sources.get(sources.size()-1), sources); + choiceDialog.setTitle("Stream Quality"); + choiceDialog.setHeaderText("Select your preferred stream quality"); + Optional selectedSource = choiceDialog.showAndWait(); + if(selectedSource.isPresent()) { + int index = sources.indexOf(selectedSource.get()); + model.setStreamUrlIndex(index); + onSuccess.apply(model); + } + } catch (InterruptedException | ExecutionException e1) { + onFail.apply(e1); + } + }); + selectStreamSource.setOnFailed((e) -> { + onFail.apply(selectStreamSource.getException()); + }); + new Thread(selectStreamSource).start(); + } +} diff --git a/src/main/java/ctbrec/ui/ThumbCell.java b/src/main/java/ctbrec/ui/ThumbCell.java index c2807126..ff0ae995 100644 --- a/src/main/java/ctbrec/ui/ThumbCell.java +++ b/src/main/java/ctbrec/ui/ThumbCell.java @@ -1,21 +1,16 @@ package ctbrec.ui; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.ExecutionException; +import java.util.function.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.iheartradio.m3u8.ParseException; import com.iheartradio.m3u8.PlaylistException; -import com.iheartradio.m3u8.data.MasterPlaylist; -import com.iheartradio.m3u8.data.PlaylistData; import ctbrec.Config; import ctbrec.HttpClient; @@ -23,7 +18,6 @@ import ctbrec.Model; import ctbrec.recorder.Chaturbate; import ctbrec.recorder.Recorder; import ctbrec.recorder.StreamInfo; -import ctbrec.recorder.download.StreamSource; import javafx.animation.FadeTransition; import javafx.animation.FillTransition; import javafx.animation.Interpolator; @@ -33,14 +27,12 @@ import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; -import javafx.concurrent.Task; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.control.Alert; -import javafx.scene.control.ChoiceDialog; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.image.Image; @@ -378,57 +370,19 @@ public class ThumbCell extends StackPane { boolean selectSource = Config.getInstance().getSettings().chooseStreamQuality; if(selectSource && start) { - Task> selectStreamSource = new Task>() { - @Override - protected List call() throws Exception { - StreamInfo streamInfo = Chaturbate.getStreamInfo(model, client); - MasterPlaylist masterPlaylist = Chaturbate.getMasterPlaylist(streamInfo, client); - List sources = new ArrayList<>(); - for (PlaylistData playlist : masterPlaylist.getPlaylists()) { - if (playlist.hasStreamInfo()) { - StreamSource src = new StreamSource(); - src.bandwidth = playlist.getStreamInfo().getBandwidth(); - src.height = playlist.getStreamInfo().getResolution().height; - String masterUrl = streamInfo.url; - String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1); - String segmentUri = baseUrl + playlist.getUri(); - src.mediaPlaylistUrl = segmentUri; - LOG.trace("Media playlist {}", src.mediaPlaylistUrl); - sources.add(src); - } - } - return sources; - } + Function onSuccess = (model) -> { + _startStopAction(model, start); + return null; }; - selectStreamSource.setOnSucceeded((e) -> { - List sources; - try { - sources = selectStreamSource.get(); - ChoiceDialog choiceDialog = new ChoiceDialog(sources.get(sources.size()-1), sources); - choiceDialog.setTitle("Stream Quality"); - choiceDialog.setHeaderText("Select your preferred stream quality"); - Optional selectedSource = choiceDialog.showAndWait(); - if(selectedSource.isPresent()) { - int index = sources.indexOf(selectedSource.get()); - model.setStreamUrlIndex(index); - _startStopAction(model, start); - } - } catch (InterruptedException | ExecutionException e1) { - Alert alert = new AutosizeAlert(Alert.AlertType.ERROR); - alert.setTitle("Error"); - alert.setHeaderText("Couldn't start/stop recording"); - alert.setContentText("I/O error while starting/stopping the recording: " + e1.getLocalizedMessage()); - alert.showAndWait(); - } - }); - selectStreamSource.setOnFailed((e) -> { + Function onFail = (throwable) -> { Alert alert = new AutosizeAlert(Alert.AlertType.ERROR); alert.setTitle("Error"); alert.setHeaderText("Couldn't start/stop recording"); - alert.setContentText("I/O error while starting/stopping the recording: " + selectStreamSource.getException().getLocalizedMessage()); + alert.setContentText("I/O error while starting/stopping the recording: " + throwable.getLocalizedMessage()); alert.showAndWait(); - }); - new Thread(selectStreamSource).start(); + return null; + }; + StreamSourceSelectionDialog.show(model, client, onSuccess, onFail); } else { _startStopAction(model, start); }