- Saved searches
- Use saved searches to filter your results more quickly
- cralcubo/pimped-radio
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Лучшие мобильные Радио & Потоковое аудио приложения для Java
- FM Radio
- Radio Stream latest app
- Ministry of Sound
- Visual-Radio
- stream Radios
- Police-Radio
- Nokia Internet Radio for Series 40
- La Vella Mobile Radio (Java)
- Радио с записью станций на языке Java
- Внешний вид
- Воспроизведение и запись
- Станции
- Разрешения на чтение и запись
- Диалоги
- Заставка
- Всплывающие сообщения, как в Android
- Сборка
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Internet Radio Player in Java
cralcubo/pimped-radio
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
This project will implement an internet radio player to be used in a computer (PC, Linux, Mac). It is called Pimped Radio because this radio player will:
- Look cool, displaying the album art of the currently playing song and information of the playing stream.
- Support of different audio streaming formats.
- Internal data base to store and classify radio stations.
The points mentioned above are the ones that will be released with Version 1.0.1
- Java 8
- JUnit/Hamcrest [Testing]
- LastFM [Find CoverArt and Album]
- vlcj-3 [The actual music player] that depends on VLC 2.2.x
- ORM Lite for the persistence of a radio stations (More info: https://github.com/cralcubo/pimped-radio-tuner)
- Java FX for the UI (More info: https://github.com/cralcubo/pimped-radio-ui)
Improvements and new features that will be developed on following versions might be:
- Searching of radio stations.
- Add extra information about the playing song such as: artist, link to buy an album and link to a video found in YouTube.
- Support for a remote control through a mobile device.
About
Internet Radio Player in Java
Лучшие мобильные Радио & Потоковое аудио приложения для Java
Любовь радио? Больной от слушания же & ldquo; Суперхитов & Rdquo; снова и снова? Вы хотите, чтобы контролировать свою музыку? Тогда проверьте Soundtrckr — вы получите бесплатный и легкий доступ к более чем 8 миллионов песен, плюс тонны социальных и на основе определения местоположения.
FM Radio
Radio Stream latest app
Радио Поток представляет собой приложение для J2ME телефонов Series 40. Он имеет 20 радио-серверов, связь, были включены в приложение. При нажатии на любую из ссылок начинает потоковое радио с сервера. Это требует хорошего качества скорости интернета для того, чтобы поток.
Ministry of Sound
В мире самый известный клуб Наконец-то! Конечной приложение от Министерства Sound — дом танцевальной музыки. Слушайте радио, смотреть видео, купить билеты, скачать музыку и многое.
Visual-Radio
Визуально-радио позволяет слушать любимые израильских радиостанций: Galgalatz, Радио Тель-Авив 103FM, 99FM, Радио Юг, радиус, резкое радио, Радио Иерусалим, сеть г и многое.
stream Radios
Сотни радиостанций различных жанров доступны в быстрой и небольшой.
Police-Radio
Слушайте радио полиции в вашем районе в любое время, днем или ночью! Эти живые потоки, каналы от реальных.
Nokia Internet Radio for Series 40
службы и ее десятки тысяч станций по всему миру. & Мидот; Слушайте десятки тысяч интернет-радиостанций & Мидот; Поиск станций по названию, жанру, языка или местоположения & Мидот; Управление избранным & Мидот; Слушать интернет-радио в фоновом режиме & Мидот; Поиск и покупка музыки Ovi.
La Vella Mobile Radio (Java)
дает вам FullAccess до более чем ста из самых горячих потокового радиостанций со всего мира, и приводит их к вашей ладони, прямо на свой мобильный телефон. Легко начать — Загрузите нашу бесплатную ла-Велья Mobile Radio Player, получить FullAccess пройти по цене от $ 2 / месяц, и обязательно иметь.
Радио с записью станций на языке Java
Привет всем! Как я уже говорил в своем первом посте, я не программист, а скорее любитель. Пробовал писать свои поделки на разных языках, но начинал я с Java. Больше всего из семейства Java мне понравилась платформа JavaFX. Точнее сказать, связка JavaFX + FXML, где в контроллере расписываем логику, а графический интерфейс описываем в отдельном fxml-файле. Радио как раз написано с помощью этой связки.
Для воспроизведения применяется библиотека JLayer. Встроенный класс MediaPlayer почему-то отказался у меня работать. Запись и воспроизведение сделаны в отдельных потоках. Ради эксперимента пробовал запустить воспроизведение в основном потоке приложения. Получил намертво зависший интерфейс. То же самое получил и при попытке записи в основном потоке.
Полностью код приложения доступен в репозитории GitHub. Приложение было создано с помощью среды разработки NetBeans 8.2 и конструктора Scene Builder от компании Gluon. В этом посте я не ставил целью полностью рассмотреть код приложения, а лишь остановился на некоторых, самых интересных, на мой взгляд, моментах.
Внешний вид
Вот так программа выглядит:
В меню «Station» находятся пункты для создания, удаления и изменения станции. В меню «Record» можно найти пункты для начала и остановки записи, а также для изменения директории записи. В меню «Reference» имеется пункт для выхода из программы и пункт «О Программе», показывающий некоторую информацию о приложении.
Содержимое файла разметки интерфейса. Все очень лаконично и понятно. Какие-то пояснения, я думаю, излишни.
Файл стилей (toast это всплывающие сообщения. О них позже):
.root < -fx-background-color: grey; >.button < -fx-background-radius: 40; -fx-border-radius: 40; -fx-text-fill: white; >.button:hover < -fx-background-color: derive(-fx-base, 18%); -fx-border-style: solid; -fx-border-width: 1; -fx-border-color: derive(-fx-base, -15%); -fx-cursor: hand; >.button:pressed < -fx-text-fill: black; >.list-view, .list-view .viewport, .list-view .content < -fx-background-color: gainsboro; >.list-view:hover < -fx-cursor: hand; >.toast < -fx-background-radius: 30; -fx-border-radius: 30; -fx-background-color: black; -fx-padding: 20; >#nameStation < -fx-text-fill: white; >#playButton < -fx-background-color: blue; >#stopButton
Воспроизведение и запись
Воспроизведение происходит с помощью этого кода:
taskPlayer = new Task() < @Override public Void call() < try < radioUrl = new URL(urlString); InputStream in = radioUrl.openStream(); InputStream is = new BufferedInputStream(in); player = new Player(is); player.play(); >catch (FileNotFoundException e) < e.getMessage(); >catch (IOException | JavaLayerException e) < e.getMessage(); >return null; > >; new Thread(taskPlayer).start();
В отличие от воспроизведения, при записи никаких сторонних библиотек не используется. Как уже говорилось, для воспроизведения применяется библиотека JLayer. Запись происходит так:
taskRecord=new Task() < @Override public Void call() throws FileNotFoundException, IOException< output = new FileOutputStream(reader(file.getAbsolutePath())+ separator+nameStation.getText()+"-"+new Date().toString().replace(":","-")+".mp3"); InputStream in = radioUrl.openStream(); InputStream is = new BufferedInputStream(in); byte data[] = new byte[1024]; int count; while ((count = is.read(data)) != -1) < output.write(data, 0, count); >output.flush(); return null; > >; new Thread(taskRecord).start();
Станции
Станции хранятся в виде текстовых файлов, где имя файла представляет собой название станции, а содержимое это ее URL. Вот метод, который создает станции при первом запуске:
private void createDefaultStations()< String[] stationNames = ; String[] stationUrls = ; for(int i=0;i <10;i++)< writer(path+separator+stationNames[i], stationUrls[i]); >>
Вызов этого метода происходит из другого метода dirCreator, который создает директорию RadioStations, где хранятся файлы станций. Вот этот метод:
private void dirCreator(final String fPath) < final File file = new File(fPath); if (!file.exists()) < file.mkdir(); if(file.exists())< alertWindow("The directory has been created.\nYour radio stations will be here:\n"+fPath); createDefaultStations(); >else < alertWindow("Error!\nThe directory will not be created.\n" + "Try creating the specified directory manually in the following path:\n"+fPath+"\nThe program will be closed."); System.exit(0); > > >
Разрешения на чтение и запись
Следующие методы проверяют разрешения на чтение и запись. Если разрешение отсутствует, то пытаются установить его:
private boolean permissionRead(File file) < if(!file.canRead())< file.setReadable(true); return !file.canRead(); >return false; > private boolean permissionWrite(File file) < if(!file.canWrite())< file.setWritable(true); return !file.canWrite(); >return false; >
Применяются эти методы в инициализаторе при проверке разрешений для папки RadioStations:
@Override public void initialize(URL url, ResourceBundle rb) < parentPath = System.getProperty("user.home"); path=parentPath+separator+"RadioStations"; this.dirCreator(this.path); File f=new File(path); if(permissionRead(f)||permissionWrite(f))< if(permissionRead(f)&&permissionWrite(f))< alertWindow("Failed to get permission to read and write files to the directory.\nTry to give permission manually."); >else if(permissionRead(f))< alertWindow("Failed to get permission to read files in directory .\nTry to give permission manually."); >else < alertWindow("Failed to get permission to write files to directory.\nTry to give permission manually."); > System.exit(0); > showStationsList(); stopButton.setDisable(true); recordItem.setDisable(true); stopRecordItem.setDisable(true); >
Диалоги
Для построения диалогов я не использовал визуальный конструктор, а писал все вручную. Например, вот диалог, который появляется перед записью. Программа спрашивает куда сохранять запись:
final Alert alert = new Alert(Alert.AlertType.CONFIRMATION); alert.setResizable(true); alert.getDialogPane().setPrefSize(500,200); alert.setTitle("Saving Recordings"); alert.setHeaderText(""); alert.setContentText("The default path for your recordings is:\n"+f.getAbsolutePath()+"\nChange?"); ButtonType buttonTypeEdit = new ButtonType("Edit", ButtonBar.ButtonData.OK_DONE); ButtonType buttonTypeDefault = new ButtonType("Default", ButtonBar.ButtonData.FINISH); ButtonType buttonTypeCancel = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE); alert.getButtonTypes().setAll(buttonTypeEdit, buttonTypeDefault, buttonTypeCancel); final Optional resultAlert = alert.showAndWait();
Конечно, программа каждый раз не будет доставать пользователя такими вопросами. Перед первой записью она покажет это окно и если пользователь выберет «Edit», то откроется окно выбора папки, а если выберет «Default», то диалог просто закроется и запись будет вестись в папку по умолчанию. «Cancel» отменяет запись.
Вот еще пример диалога. Это диалог добавления станции:
Dialog dialog = new Dialog<>(); dialog.setTitle("Station Creation"); dialog.setHeaderText("Enter the name and url of the radio station"); ButtonType createButtonType = new ButtonType("Create", ButtonBar.ButtonData.OK_DONE); ButtonType cancelButtonType = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE); dialog.getDialogPane().getButtonTypes().addAll(createButtonType,cancelButtonType); GridPane grid = new GridPane(); grid.setHgap(10); grid.setVgap(10); grid.setPadding(new Insets(20, 150, 10, 10)); TextField stationName = new TextField(); TextField url = new TextField(); grid.add(new Label("Title:"), 0, 0); grid.add(stationName, 1, 0); grid.add(new Label("Url:"), 0, 1); grid.add(url, 1, 1); dialog.getDialogPane().setContent(grid); Optional result = dialog.showAndWait();
Здесь все просто. Получаем окно с двумя текстовыми полями. Вот такое:
Окно диалога для изменения станций такое же, только поля заполнены данными изменяемой станции.
Заставка
Перед запуском приложения сначала появляется заставка. Для этого в проект был добавлен специальный класс. В настройках запуска проекта его нужно указать как стартовый.
package radioplayer; import javafx.application.Application; import java.awt.*; import javafx.stage.Stage; /** * * @author alex */ public class Splash extends Application < public static void main(final String[] args) < SplashScreen splash = SplashScreen.getSplashScreen(); try < Thread.sleep(3000L); >catch (InterruptedException ex) < ex.getMessage(); >if (splash != null) < splash.close(); Application.launch(RadioPlayer.class, args); >> @Override public void start(Stage primaryStage) throws Exception < throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. >>
Там же в настройках нужно указать следующие параметры для виртуальной машины:
В манифест приложения следует добавить:
SplashScreen-Image: images/splash.png
Всплывающие сообщения, как в Android
В приложении имеются всплывающие сообщения, которые выглядят как подобные сообщения в Android OS. Вот пример сообщения:
За их появления отвечает отдельный класс:
package radioplayer; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.util.Duration; /** * * @author alex */ public class Toast < void setMessage(final String toastMsg)< Stage toastStage=new Stage(); toastStage.setResizable(false); toastStage.initStyle(StageStyle.TRANSPARENT); Text t = new Text(toastMsg); t.setFont(Font.font("Verdana",20)); t.setFill(Color.WHITE); StackPane root = new StackPane(t); root.getStyleClass().add("toast"); root.setOpacity(0); Scene scene = new Scene(root); scene.getStylesheets().add((getClass().getResource("style.css")).toExternalForm()); scene.setFill(null); toastStage.setScene(scene); toastStage.show(); Timeline tl1 = new Timeline(); KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(500),new KeyValue (toastStage.getScene().getRoot().opacityProperty(), 1)); tl1.getKeyFrames().add(fadeInKey1); tl1.setOnFinished((ae) ->new Thread(() -> < try < Thread.sleep(3000); >catch (InterruptedException e) < e.getMessage(); >Timeline tl2 = new Timeline(); KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(500), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 0)); tl2.getKeyFrames().add(fadeOutKey1); tl2.setOnFinished((aeb) -> toastStage.close()); tl2.play(); >).start()); tl1.play(); > >
Сборка
Если создавать исполняемый архив, просто нажав в NetBeans кнопку очистки и сборки проекта, мы получим архив, который не будет содержать в себе классы библиотеки JLayer. В манифесте этого архива будет прописан путь до библиотеки. Программа будет работать, только если библиотека будет расположена по этому пути.
Чтобы классы библиотеки JLayer запаковать в исполняемый архив, нужно в файле build.xml дописать следующее:
/$.jar"/> into a single JAR at $"/> "/> "/> /temp_final.jar"/>
Для сборки в меню нужно выбрать «выполнить цель», а в подменю найти «package-for-store». В папке «store» появится готовый архив.
Дополнительная ссылка на SourceForge. До встречи в следующих постах!