Логотип Electron
Логотип Electron
Фреймворк Electron разработан в GitHub и носил раньше название Atom shell. Пожалуй, самое известное приложение, написанное с его помощью, — текстовый редактор Atom, а еще — клиент Slack для настольных компьютеров, которым очень активно пользуются в нашей редакции. Из других интересных проектов — мультипротокольный клиент мгновенных сообщений Franz, Git-клиент GitKraken, GUI-клиент к хорошо известной Node.js-разработчикам утилите Yeoman yeoman-app и даже Microsoft Visual Studio Code.

Electron позволяет создавать кросс-платформенные приложения для настольных компьютеров с использованием чистого JavaScript. Поддерживаются основные операционные системы: macOS, Linux, Windows. Он сочетает в себе лучшие стороны Node.js и Chromium, но при этом ориентирован на разработку десктопных приложений.

Само собой напрашивается сравнение Electron с проектом Cordova, который аналогичным образом позволяет превратить веб-приложение в мобильное приложение для основных мобильных платформ. Так когда же нам может пригодиться именно Electron? Варианты следующие:

  • если требуется кросс-платформенное приложение с малыми затратами на разработку и сопровождение;
  • если есть готовое веб-приложение или веб-компонент, который необходимо распространять в виде законченного приложения для настольных компьютеров;
  • если веб-приложению требуются права, выходящие за рамки ограничений системы безопасности браузеров;
  • если веб-приложение должно требовать большей интеграции с операционной системой и доступа к API, невозможного из браузера.

WWW


Читаем доки здесь. Перевод на русский язык здесь.
 

Что будем делать

Мы возьмем готовый виджет, «обернем» его в приложение Electron и добавим стандартные элементы интерфейса операционной системы, такие как иконка в области уведомлений, стандартные системные диалоги, вызов внешнего приложения, главное меню, горячие клавиши.

Для наших экспериментов возьмем готовый виджет платформы SoundCloud, популярной площадки для публикации музыкальных композиций и другого аудиоконтента. Этот виджет обладает несложным API, да и можно будет немного поразвлечься прослушиванием музыки. Мы превратим его в простой проигрыватель для настольного компьютера с привычными элементами управления.

 

Подготовка

 

Иконки

Для приложения нам понадобится несколько иконок. Я брал их из набора ie_Bright с сайта iconfinder.com; можно взять другие на свой вкус. Для изображений, используемых для иконки в области уведомлений под Windows, рекомендуются файлы .ico, но мы для простоты возьмем только PNG-файлы.

Имя файла Назначение Изображение
player.png Иконка приложения
player.png
player.png
play.png Начать проигрывание
play.png
play.png
pause.png Приостановить
pause.png
pause.png
prev.png Предыдущая композиция
prev.png
prev.png
next.png Следующая композиция
next.png
next.png

Поместим иконки в подкаталог assets/img/ проекта.

 

Node.js

Предполагается, что на компьютере установлен Node.js версии не ниже 6.6; загрузить ее можно здесь.

$ node -v
v6.6.0
 

Операционная система

Примеры подготовлены для выполнения на компьютере, работающем под управлением ОС Linux и macOS.

 

Минимальное приложение Electron

Начнем с создания минимального приложения Electron. Для этого создадим каталог проекта, например electron-demo, и перейдем в него:

$ mkdir electron-demo
$ cd electron-demo

Добавим в наш проект два файла — минимальный index.html, который будет основным интерфейсом нашего приложения:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    Welcome to Electron!
</body>
</html>

и index.js со следующим содержимым:

const path = require('path')
const electron = require('electron')
const {app, BrowserWindow} = electron

// Ссылка на объект окна; если ее не будет, окно закроется автоматически, когда сборщик мусора высвободит память из-под объекта JavaScript
let win = null

// Путь к иконкам приложения
const iconBasePath = path.join(__dirname, 'assets', 'img')


// Создание окна браузера и обработка его событий
function createWindow () {
    const APP_ICON_NAME = 'player.png'
    const iconPath = path.join(iconBasePath, APP_ICON_NAME)

    // Задаем параметры для создания окна браузера
    let options = {
        width: 800, height: 550,
        title: 'Electron SoundCloud Player', // Не будет работать, если в `.html` есть тег `title`
        icon: iconPath,
        webPreferences: {
            devTools: true, // По умолчанию — `true` для показа DevTools
        }
    }
    // Создаем окно браузера
    win = new BrowserWindow(options)

    // и загружаем index.html приложения
    win.loadURL(`file://${__dirname}/index.html`)

    // Событие во время закрытия окна
    win.on('closed', (e) => {
        // Это то время, когда нужно удалить соответствующий объект
        // Убираем ссылку на объект окна. В многооконных приложениях окна обычно будут храниться в массиве
        win = null
    })

    let webContents = win.webContents

    // Открываем DevTools
    webContents.openDevTools()
}

// Этот событие произойдет, когда Electron завершит
// инициализацию и будет готов к созданию окон браузера
// Многие методы API могут использоваться только после этого события
app.on('ready', createWindow);

// Выйти из приложения, когда все окна закрыты
app.on('window-all-closed', () => {
    // На macOS приложения и их меню остаются активными до тех пор, пока
    // пользователь не выйдет из них явно с помощью Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', () => {
    // На macOS, как правило, при клике на иконке в доке (и если нет других
    // открытых окон), окно в приложении пересоздается
    if (win === null) {
        createWindow()
    }
})

Инициализируем файл package.json проекта менеджера пакетов npm, ответив на необходимые вопросы.

$ npm init

Нужно проверить, что в package.json, получившемся в результате, значение свойства main равно main.js (соответствует значению, введенному при запросе entry point во время выполнения команды npm init), в противном случае его необходимо скорректировать вручную, чтобы оно соответствовало имени главного .js-файла проекта.

Electron можно установить только для нашего проекта:

$ npm install --save electron

или глобально:

$ npm install -g electron

Пора запускать! Если Electron был установлен локально, это делается следующей строкой (если он был установлен глобально, путь указывать необязательно):

$ ./node_modules/.bin/electron .

Через несколько мгновений откроется окно нашего первого приложения.

Первое приложение
Первое приложение

Обрати внимание, что сразу же открыто привычное окно DevTools. Заголовок и текст окна соответствуют заданным; кроме того, у приложения есть типовое главное меню.

 

Виджет SoundCloud

Виджет SoundCloud встраивается в веб-страницу как IFrame и позволяет проигрывать отдельные композиции с сайта SoundCloud или их списки. Он предоставляет базовый интерфейс для управления проигрыванием и разнообразную информацию о композиции.

 

API виджета

Методы виджета

Из методов API виджета для управления проигрыванием мы будем использовать следующие:

  • play — начать проигрывание композиции;
  • pause — приостановить проигрывание композиции (пауза);
  • toggle — переключить проигрывание / приостановка;
  • prev — перейти к предыдущей композиции (для списка);
  • next — перейти к следующей композиции (для списка);
  • bind — добавить обработчик события виджета.

В числе прочих методов: skip, load, seekTo, setVolume, unbind.

События виджета

События виджета делятся на две группы: аудиособытия и события пользовательского интерфейса.

Аудиособытия связаны с проигрываемой композицией и уведомляют об изменениях ее состояния в проигрывателе, передавая объект с информацией о текущей позиции в проигрываемом файле или прогрессе загрузки (relativePosition, loadProgress, currentPosition).
События пользовательского интерфейса виджета уведомляют о действиях пользователя, не связанных напрямую с проигрыванием композиции.

Мы используем следующие события:

  • READY — виджет загрузил данные и готов принимать внешние вызовы;
  • PLAY — начато проигрывание композиции;
  • PAUSE — проигрывание композиции приостановлено.

Остальные события: LOAD_PROGRESS, PLAY_PROGRESS, FINISH, SEEK, CLICK_DOWNLOAD, OPEN_SHARE_PANEL, ERROR.

Дополнительно можно получить информацию о текущем состоянии виджета с помощью методов getVolume, getDuration, getPosition, getSounds, getCurrentSound, getCurrentSoundIndex, isPaused. Информация возвращается в callback-функции. Из них нам понадобится метод getCurrentSound, возвращающий информацию о текущей композиции.

 

Добавление виджета на страницу

Для того чтобы отобразить на нашей странице виджет SoundCloud, внутри элемента <body> добавим элемент <iframe>, в котором загрузится сам виджет:

<!-- виджет SoundCloud -->
<iframe id="sc-widget" width="100%" height="450" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/playlists/178009618&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe>

Полный список параметров виджета приведен здесь: SoundCloud Player Widget — Customize Parameters (для предыдущей версии, использующей Flash).

Для выбора композиции или их списка и настройки визуального представления виджета можно нажать кнопку Share на понравившемся списке композиций (если выбрана отдельная композиция, то будет невозможно перемещаться к следующей/предыдущей композиции), выбрать закладку Embed и скопировать предлагаемый код; установив галочку More Options, можно настроить несколько дополнительных параметров.

Можем перезапустить приложение, чтобы убедиться, что виджет действительно загрузился внутри нашего приложения.

 

Инициализация API виджета SoundCloud

Для доступа к API виджета необходимо добавить в тег <head> загрузку следующего сценария:

<script src="https://w.soundcloud.com/player/api.js" type="text/javascript"></script>

Туда же добавим загрузку файла, в котором будут размещаться основные функции браузерной части приложения:

<script src="./soundcloud.js" type="text/javascript"></script>

А тег <body> дополним кнопками управления проигрыванием:

<div>
  <button id="action-widget-play">Play</button>
  <button id="action-widget-pause">Pause</button>
  <button id="action-widget-toggle">Toggle</button>
  <button id="action-widget-prev">Prev</button>
  <button id="action-widget-next">Next</button>
</div>

Создадим файл soundcloud.js, добавив в него функцию, которая будет выполняться при загрузке окна браузера:

let initSC = function() {
  const {ipcRenderer} = require('electron')

  let widgetIframe = document.getElementById('sc-widget'), // IFrame виджета
      widget       = SC.Widget(widgetIframe)               // Сам виджет
  console.log('widget:', widget)
}

И собственно вызов этой функции по событию window onload:

// Вызвать основную функцию по событию onload объекта window
window.addEventListener('load', function load(event){
    // Удалить listener, так как он больше не нужен
    window.removeEventListener('load', load, false)
    // Вызов основного метода
    initSC()
}, false)

Теперь при запуске приложения в консоль должен быть выведен объект widget.

 

Методы и события API виджета SoundCloud

Привяжем методы виджета, предназначенные для управления проигрыванием композиции, напрямую к кнопкам управления на странице (в функции initSC):

Продолжение статьи доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все статьи на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта, включая эту статью. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи одну статью

Заинтересовала статья, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для статей, опубликованных более двух месяцев назад.


2 комментария

Подпишитесь на ][, чтобы участвовать в обсуждении

Обсуждение этой статьи доступно только нашим подписчикам. Вы можете войти в свой аккаунт или зарегистрироваться и оплатить подписку, чтобы свободно участвовать в обсуждении.

Check Also

Цифровой паноптикум. Настоящее и будущее тотальной слежки за пользователями

Даже если ты тщательно заботишься о защите своих данных, это не даст тебе желаемой приватн…