2012-01-28 19 views
9

Estoy desarrollando una aplicación que tiene varias listas de reproducción de música, una vista para cada lista de reproducción y un reproductor.La arquitectura de un reproductor de música con listas de reproducción, usando Rails, Redis y HTML5

Estoy usando el sistema HTML5 History API en mi sistema ya (para otras funciones) y lo usaré más para evitar que la página se vuelva a cargar entre solicitudes y, por lo tanto, la música se detenga en cada página.

Estoy atascado en cuanto a la mejor manera de gestionar las pistas que el jugador jugará entre las vistas. Actualmente, como era de esperar, un usuario hace clic en un enlace y obtiene una lista de pistas. Las pistas se cargan en el reproductor y se reproducen de forma secuencial, simple. Sin embargo, con la reproducción continua de música, necesito asegurarme de que la lista de reproducción correcta de las pistas se reproduce en orden a pesar del contenido cambiante en la página y ahora es una URL dinámica.

Sin embargo, cuando el usuario navega a otra página, presiona play en una pista en la nueva lista de reproducción, necesito poder cargar ese elemento en el reproductor y cargar efectivamente el resto de la lista de reproducción mientras el usuario continúa para navegar.

Estoy usando Redis para almacenar una lista de las identificaciones de las pistas para una lista de reproducción, para una referencia rápida para reducir el desfase entre las pistas. Como resultado, tengo un conjunto diferente de Redis para cada lista de reproducción. También he creado mis llamadas a la API de seguimiento siguiente y anterior en función de la reproducción de la pista actual, de modo que la siguiente pista del conjunto de Redis pueda cargarse en el reproductor.

Como mencioné, no puedo decidir la mejor manera de referenciar qué lista de reproducción se está reproduciendo actualmente para que el jugador sepa desde qué redis configuró las pistas. Mi pensamiento me ha dejado algunas ideas diferentes:

a) Atributos de datos HTML5 personalizados - podría configurar la lista de reproducción que se está reproduciendo actualmente como un atributo de datos en el reproductor y actualizarla como y cuando. Podría hacer referencia a este atributo al decidir de qué redis se configurará para cargar mi siguiente pista.

Alternativamente podría volcar la lista de reproducción actual, y todas las pistas (y sus atributos) como objetos JSON en atributos de datos en la página. Las listas de reproducción podrían tener miles de pistas, así que descarto esta porque el código fuente se vería horrible, y mucho menos los posibles problemas de rendimiento asociados. Estoy en lo correcto?

b) LocalStorage - La compatibilidad con navegadores cruzados es limitada. Mientras más soporte para esta solución, mejor en este caso particular. A pesar de esto, podría guardar la lista de reproducción actual en el navegador de los usuarios. Esto me llevó a preguntarme si también sería práctico guardar las pistas de los objetos JSON en LocalStorage también, para evitar las llamadas DB adicionales.

c) En la sesión - Pude actualizar la sesión para almacenar una variable para la lista de reproducción actualmente en reproducción.

d) Redis - Pude expandir el uso de Redis para guardar una cadena que hace referencia al nombre de la lista de reproducción actual. Podría verificarlo entre cada llamada de seguimiento siguiente/anterior.

Al escribir esta pregunta ya tengo una mejor idea de qué ruta tomaré, pero si alguien tiene algún consejo para este escenario, me encantaría saberlo.

Gracias.

ACTUALIZACIÓN: Implementé el 95% de una solución que hace uso de Redis para esto. Aunque estoy teniendo algunos problemas de rendimiento con páginas que tardan ~ 10s en cargarse. No es genial en absoluto.

Esencialmente, cada usuario tiene 2 listas de reproducción: actual y armada. Cada solicitud carga la identificación de la pista en la lista de reproducción de Redis Armed y si se presiona el botón de reproducción en una pista, la lista de reproducción actual Redis expira y se reemplaza por la armada.

Mis botones Siguiente y Anterior solo tienen que buscar el ID de la pista siguiente o anterior en la lista de reproducción actual y cargar la fuente de música del reproductor. El concepto funciona bien y estoy satisfecho con él.

Sin embargo, como el rendimiento mencionado es lento entre las solicitudes de página y necesita una mejora significativa. Mi SQL está optimizado, solo estoy sacando los atributos requeridos y tengo índices SQL cuando es necesario, así que estoy buscando otras alternativas en este momento.

Opciones estoy considerando:

  1. pueblan Sólo la lista de reproducción armada si se hace clic en una pista en la nueva página. Esto ahorraría procesamiento adicional si el usuario no quiere escuchar una de las pistas nuevas.

  2. Haciendo más uso de Redis y almacenando los objetos de pista delgada dentro de las listas de reproducción Redis en lugar de solo la ID de pista. Sin embargo, el retraso de rendimiento es mayor entre solicitudes de página y no en la reproducción real de pistas y navegando por una lista de reproducción.

  3. Haz uso de una lista de reproducción maestra de Redis que contiene todas las pistas de aplicaciones de las que pueden elegir las listas de reproducción actual y armada. Esto podría mantenerse a través de una tarea de rake por hora y evitaría largas llamadas a bases de datos en las solicitudes de página. Estoy nervioso por lo lejos que esto podría escalar en términos de uso de memoria en el servidor y la cantidad de pistas en el DB.

Respuesta

0

Sugeriría c) En sesión.
Se puede acceder a los datos de sesión con relativa facilidad tanto en el lado del cliente como del servidor.

Llenar la memoria caché de Redis con datos de usuario específicos no aumenta especialmente.

LocalStorage - corregir, esto no funcionará para un gran% de usuarios en la fecha actual.

Atributos de CustomData - simplemente desordenados, como notado.

Sólo mis 2 centavos.

1

Si necesita modelar el estado de la aplicación del lado del cliente, es mejor tener una fuente del estado. Este es uno de los problemas que intentan resolver los marcos javascript MV (V) C del lado del cliente. Estoy familiarizado con backbone.js y ember.js, así que puedo hablar con ellos.

Backbone.js

Crear un modelo llamado Playlist y una colección llamada Playlists. Agregue una propiedad a su colección PlaylistscurrentPlaylist que contiene la lista de reproducción actual. Luego defina una vista llamada PlaylistView y defina un método render en ella.Establezca los desencadenadores y desencadenantes de eventos de manera que cuando currentPlaylist cambie, la lista de reproducción se vuelva a generar automáticamente. Esto requeriría mover la representación de la plantilla al cliente, pero es probable que desee hacerlo de todos modos para reducir las vueltas del servidor y reducir la carga en el servidor causada por el procesamiento.

Ember.js

Crear un controlador (similar a la recogida de la columna vertebral) con una propiedad llamada currentPlaylist y poblar el controlador con todas las listas de reproducción representados como Ember.object s. Luego, en una plantilla de barra de herramientas de la lista de reproducción incluida en la página, puede enlazar al playlists.currentPlaylist y la plantilla se volverá a procesar automáticamente cuando cambie playlists.currentPlaylist.

Obviamente, omitiré la gran mayoría de los detalles, pero es mejor dejar la documentación del marco, los ejemplos y los tutoriales.

descargo de responsabilidad: Soy nuevo en los marcos del lado del cliente, que es parte de la razón por la que omite la mayoría de los detalles. Agradezco a cualquiera que pueda corregirme si estoy equivocado.

+0

Gracias por la sugerencia Patrick. No he bajado el framework Javascript MVC todavía, aunque no tengo dudas de que un poco más adelante será necesario para facilitar la carga del servidor. – Pete

1

Una combinación de sesión y almacenamiento local sería un buen enfoque.

Pero en lugar de buscar toda la lista de reproducción, simplemente busque la X (por ejemplo 10) las siguientes pistas y tal vez también las X anteriores. Una vez que el jugador llega a la última canción, busca las siguientes 10 canciones, las anteriores pueden calcularse en el cliente.

El modelo de datos podría ser simplemente un hash donde el elemento [0] es la canción actual, los elementos [X] son ​​las siguientes canciones y [-X] los anteriores.

Almacenamiento de la información del lado del cliente lista de reproducción me parece razonable, pero también se puede utilizar la sesión para hacer referencia a la canción y la lista de reproducción actual, de modo que cuando un usuario regresa o realmente vuelve a cargar su sitio sigue recibiendo la canción sin hacer una llamada a la base de datos

+0

Esto suena similar al enfoque con el que realmente me he ido. Estoy teniendo algunos problemas con el rendimiento, ya que en realidad estoy obteniendo toda la lista de reproducción actualmente, que se volverá exponencialmente más lenta a medida que se agreguen más pistas a cada lista de reproducción. Sin embargo, estoy implementando lo que sugirieron, simplemente buscando las próximas 10 pistas y cuando llegue al último, ve a buscar un poco más. Gracias por la sugerencia. – Pete

+0

De nada :) – yagooar

Cuestiones relacionadas