Мы будем использовать Quasar и WaveSurfer для создания межплатформенного мобильного аудиоплеера, подобного SoundCloud. Мы загрузим локальный аудиофайл с устройства, используя ввод HTML-файла, визуализируем форму волны и добавим элементы управления для воспроизведения звука.

Квазар?

Quasar - это UI-фреймворк, построенный на Vue.js. Он кажется более ориентированным на мобильные устройства, чем Vuetify, а также имеет отличный интерфейс командной строки, который отлично подходит для создания приложений Cordova. Вы получаете отладку на реальном устройстве с горячей перезагрузкой прямо из коробки. Это важная часть эффективного процесса разработки и один из определяющих факторов для меня при выборе фреймворка / стека.

Еще несколько моментов, которые заставили меня попробовать:

  • Яркое и активное сообщество (11 тысяч звезд на GitHub)
  • Отличный интерфейс командной строки
  • Встроенные красивые компоненты пользовательского интерфейса и сеточная система (мне нравится писать как можно меньше CSS)
  • Используйте экосистему Vue, которую вы знаете и любите

Строительные леса

Я предполагаю, что у вас уже есть работающая установка Cordova с настроенным android studio / xcode. Просто следуйте руководству по квазару

Начнем с установки Quasar CLI. Из вашего терминала рабочего пространства запустите:

npm install -g @quasar/cli

Затем создайте проект:

quasar create quasar-wavesurfer-audio-player

Вставьте следующие ответы:

  • Название проекта: по умолчанию
  • Название продукта проекта: изменить на «Cool Player»
  • Описание проекта: Аудиоплеер, похожий на звуковое облако, использующий квазар и вейсерфер.
  • Автор: ты
  • Особенности: нам не нужны никакие функции
  • Идентификатор Кордовы: оставьте как есть, если вы не хотите публиковать в магазине (ах)

Quasar CLI установит необходимые пакеты. После этого войдите в папку и запустите quasar dev, чтобы увидеть базовый макет:

cd quasar-wavesurfer-audio-player quasar dev

Рабочая версия! Сейчас хорошее время для запуска репозитория git и выполнения первого коммита.

Добавление режима кордовы

Теперь у нас есть приложение Quasar, работающее в режиме SPA. Чтобы превратить его в мобильное приложение, которое мы затем сможем опубликовать в магазине приложений, нам нужно добавить cordova mode Quasar:

Эта команда CLI Quasar добавляет папку src-cordova, содержащую наш проект Cordova. В этой папке мы можем запустить любую команду Cordova CLI. Quasar соберет наш код Vue и поместит ресурсы в папку src-cordova/www.

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

Убедитесь, что ваше устройство подключено по USB, и запустите:

Примечание. Новые версии Chrome по умолчанию блокируют открытый текстовый трафик, поэтому внутренний WebView Cordova выдает ERR_CLEARTEXT_NOT_PERMITTED ошибку. Чтобы решить эту проблему, раскомментируйте https: true, в разделе devServer в quasar.conf.js

Примечание 2. Если вы разрабатываете для iOS, рекомендуется обновить устаревший UIWebView (который Кордова использует по умолчанию) до WKWebView, используя один из методов, описанных здесь

Теперь CLI спрашивает, на каком IP работать. Выберите IP-адрес, доступный с вашего мобильного устройства (они должны быть в одной сети). Quasar создаст приложение Cordova, которое загружает внутренний WebView с этого IP-адреса, тем самым давая нам возможность разрабатывать с горячей перезагрузкой на нашем устройстве. Это важная функция для эффективного процесса разработки.

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

Если вы создаете приложение, которое хотите работать на Android и iOS, я рекомендую периодически запускать его на обеих платформах. Они никогда не повторяются.

Структура проекта Quasar

Теперь давайте взглянем на структуру проекта, созданную для нас интерфейсом командной строки, для быстрого обзора Quasar. Quasar CLI формирует структуру папок с макетом по умолчанию MyLayout.vue внутри layouts папки. Макет - это компонент Vue, в котором есть все элементы пользовательского интерфейса Quasar, включая панель навигации, панель инструментов и главную страницу. Вы можете заметить компоненты Quasar, начинающиеся с q-, например. q-layout, q-toolbar и т. Д. Это все компоненты Vue, написанные командой Quasar (аналогично v- компонентам Vuetify).

Чтобы использовать компонент пользовательского интерфейса Quasar, вам необходимо явно включить их в quasar.conf.js, как мы увидим позже.
Главная страница содержится внутри элемента<q-page-container> в MyLayout.vue, который содержит <router-view /> - тот же vue-router, который вы знаете и любовь. Маршруты сохраняются в папке pages.

По умолчанию загружается главная страница Index.vue в папке pages, поэтому мы добавим туда наш код для этого примера.

Добавление wavesurfer.js

WaveSurfer - это аудиоплеер с открытым исходным кодом, который отображает звуковую волну на холсте html5. Добавим:

Теперь мы импортируем WaveSurfer в Index.vue, добавим wavesurfer элемент данных и метод createWaveSurfer, который инициализирует его при монтировании компонента. Объекту wavesurfer требуется container, который является идентификатором html-элемента, в котором он будет отображаться. Поэтому мы также добавим контейнер div в шаблон компонента. На этом этапе мы загрузим демонстрационный mp3-файл только для тестирования. Вот как сейчас выглядит Index.vue:

<template>
  <div id="waveform"></div>
</template>

<script>
import WaveSurfer from "wavesurfer.js";

export default {
  name: 'PageIndex',
  data: () => ({
    wavesurfer: null,
  }),
  async mounted() {
    if (!this.wavesurfer) this.createWaveSurfer();
  },
  methods: {
    createWaveSurfer() {
      this.wavesurfer = WaveSurfer.create({
        container: "#waveform",
        barWidth: 3
      });
      this.wavesurfer.load(
        "https://ia902606.us.archive.org/35/items/shortpoetry_047_librivox/song_cjrg_teasdale_64kb.mp3"
      );
    }
  }
}
</script>

Запустив quasar dev, вы должны увидеть визуализированный сигнал:

Загрузка локального аудиофайла

Мы будем использовать <input type="file"> HTML-код для загрузки файлов с локального устройства. Давайте добавим кнопку загрузки файла на нашу панель инструментов. В MyLayout.vue замените <div>Quasar v{{ $q.version }}</div> на q-btn компонент:

<q-btn color="white" text-color="primary">
Load File
<input
    type="file"
    class="q-uploader__input overflow-hidden absolute-full"
    v-on:change="fileChosen"
    ref="fileInput"
    accept="audio/mpeg"
/>
</q-btn>

У нас есть <q-btn> (кнопка Quasar), содержащая обычный элемент html <input> с type="file" (что делает его средством выбора файлов), который принимает только аудиофайлы (accept="audio/mpeg").

Обратите внимание, что браузеры пытаются принудительно использовать ввод файлов, чтобы иметь один из самых уродливых дизайнов в Интернете, примерно так:

Хотя официального способа изменить внешний вид вводимого файла не существует, мы «позаимствуем» классы css из компонента Quasar q-uploader, чтобы он выглядел больше как кнопка, а не как пережиток 90-х. При нажатии на нее в приложении Cordova откроется интерфейс выбора файлов на собственном устройстве.

В разделе методов добавьте обработчик получения файла:

fileChosen(file) {
    // Chosen file passed as argument
}

Отправка файла на главную

Поскольку у нас есть объект файла, полученный в компоненте MyLayout, но объект волнового серфера в компоненте Index, мы будем использовать шину событий для связи между ними и отправки файла, когда он выбран. Шину событий можно легко создать с помощью другого объекта Vue. Добавьте папку services с новым файлом event-bus.js, содержащим:

import Vue from 'vue';
export const EventBus = new Vue();

Мы импортируем его в MyLayout.vue и генерируем событие при изменении входного значения файла:

import { EventBus } from "../services/event-bus.js";

...

methods: {
    fileChosen(file) {
        EventBus.$emit("fileChosen", file);
    }
}

Теперь нам нужно поймать событие в обработчике Index.vue mounted:

import { EventBus } from "../services/event-bus.js";

...
mounted() {
    ...

    EventBus.$on("fileChosen", file => {
        this.loadFile(file);
    });
}

И, наконец, загрузим файл с помощью loadBlob метода waveurfer:

loadFile(file) {
    if (file.target.files.length == 0) return;

    this.wavesurfer.loadBlob(file.target.files[0]);
}

Попробуйте загрузить файл со своего устройства, и вы увидите, что он отрисован:

Добавление элементов управления

Давайте добавим несколько кнопок воспроизведения / паузы / пропуска. В Index.vue добавьте следующий код в раздел шаблона:

<template>
  <q-page class>
    <div class="audio-container">
      <div class="row q-ma-md">
        <div class="col-12">
          <div id="waveform"></div>
        </div>
      </div>
    </div>
    <div class="controls row flex flex-center fixed-bottom q-pb-md q-pt-md shadow-10">
      <div class>
        <q-btn
          color="primary"
          flat
          round
          icon="fast_rewind"
          size="xl"
          @click="wavesurfer.skipBackward(1)"
        />
        <q-btn
          v-if="isPlaying"
          color="primary"
          round
          icon="pause"
          size="xl"
          @click="wavesurfer.playPause()"
        />
        <q-btn
          v-if="!isPlaying"
          color="primary"
          round
          icon="play_arrow"
          size="xl"
          @click="wavesurfer.playPause()"
        />
        <q-btn
          color="primary"
          flat
          round
          icon="fast_forward"
          size="xl"
          @click="wavesurfer.skipForward(1)"
        />
      </div>
    </div>
  </q-page>
</template>

И в разделе скрипта:

computed: {
    isPlaying() {
      if (!this.wavesurfer) return false;

      return this.wavesurfer.isPlaying();
    }
},

Мы добавили некоторые элементы управления с помощью <q-btn> компонентов Quasar в блок Quasar "row", который аккуратно упорядочивает их с помощью помощников позиционирования flex, fixed-center и fixed-bottom. q-pb-md/q-pt-md дает нам несколько предопределенных полей. Обработчики @click напрямую вызывают методы волнового серфера.

Обратите внимание, как мы декларативно разрабатываем пользовательский интерфейс с использованием раздела шаблонов с такими модификаторами Quasar, как round, flat и size. Это экономит нам 99% CSS, который нам придется писать вручную.

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

Использование крючков для вейсерфера для добавления счетчика загрузки

Почти сделано! Теперь мы добавим счетчик, чтобы дать пользователю обратную связь при загрузке файла. Wavesurfer предоставляет несколько хуков, чтобы мы могли обрабатывать различные события. Мы будем использовать события error, loading и ready.

В разделе quasar.conf.js компонентов добавьте 'QCircularProgress' в список. Затем в Index.vue над кнопкой воспроизведения добавьте q-circular-progress:

<q-circular-progress v-if="isLoading" size="72px" indeterminate color="primary" />

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

<q-btn v-if="!isPlaying && !isLoading" 
...

Добавьте член isLoading в раздел data:

isLoading: false

А в методе createWaveSurfer() мы подключимся к событиям вейсерфера:

this.wavesurfer.on("error", err => {
    console.error(err);
    this.isLoading = false;
    this.$q.notify({ message: err });
});

this.wavesurfer.on("loading", () => {
    this.isLoading = true;
});

this.wavesurfer.on("ready", () => {
    this.isLoading = false;
});

Мы также добавили уведомление Quasar (панель закусок) при возникновении ошибки. В Quasar это делается очень просто, используя this.$q.notify из любого места вашего кода.

Немного дизайна

Чтобы завершить дизайн, мы добавим красивое фоновое изображение и немного стиля на форму волны. Я использовал фотографию Джеймса Оуэна в качестве фона. Сохраните изображение как audio.png в папке assets и установите его в качестве фона нашего основного div, используя следующий CSS:

.controls {
  background-color: white;
}
.audio-container {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
    url("../assets/audio.jpg") no-repeat center;
  background-size: cover;
}

И немного стиля для формы волны с использованием параметров WaveSurfer:

this.wavesurfer = WaveSurfer.create({
    container: "#waveform",
    hideScrollbar: true,
    waveColor: "white",
    progressColor: "hsla(200, 100%, 30%, 0.5)",
    cursorColor: "#fff",
    barWidth: 3
});

Вот и все!

Резюме

Я обнаружил, что Quasar - это очень быстрый способ разработки хорошо спроектированных мобильных / настольных / веб-приложений с использованием Vue с очень небольшим количеством CSS. Интерфейс командной строки также довольно хорош и избавляет от многих проблем с настройкой Cordova.

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

Ссылки

Первоначально опубликовано на https://www.learningsomethingnew.com.