web-dev-qa-db-fra.com

Lecteur Soundcloud intégré sur mobile

Voici à quoi ressemble un lecteur SoundCloud intégré sur une page HTML sur un appareil mobile:

 enter image description here

C'est plutôt gênant, parce que l'utilisateur doit cliquer sur "Écouter dans le navigateur", puis, souvent, cela ne démarre pas comme il le devrait, et l'utilisateur doit donc cliquer sur le bouton "Pause" et "Lire" à nouveau.

Comment avoir l'apparence normale, même sur les appareils mobiles? :

 enter image description here


Voici un exemple de code d'intégration:

<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/271188615&amp;color=ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false"></iframe>
11
Basj

Je vais suggérer de ne pas utiliser d'iframe intégré pour le lecteur mais d'utiliser l'API HTTP de SoundCloud .

Ma réponse ne met l'accent sur aucune méthode pour inciter le code iframe intégré à ne pas penser qu'il est mobile. Au lieu de cela, je montre un chemin alternatif à la façon de faire votre propre lecteur SoundCloud. 

Faire cela garantit:

  • Vous avez le plein contrôle de votre interface utilisateur
  • Vous avez un contrôle total sur la lecture

Je suis allé de l'avant et construit un exemple d'application dans Android. En supposant que vous recherchiez Android ici à cause de la barre d'état dans l'image de la question postée. 

Aussi, comme demandé, il existe un projet Web, qui fonctionnera sur mobile. Le projet Web utilise le wrapper JavaScript de SoundCloud pour api. 

_ {Mise à jour le 20 octobre 2016: J'ai effectué des recherches sur la lecture automatique sur mobile dans un navigateur Web. Il s'avère qu'il y a beaucoup de bonnes questions pour répondre à cette question. Malheureusement, j'en suis arrivé à la conclusion que ce n'est pas possible. "Lecture automatique" Lecteur audio HTML5 sur les navigateurs mobiles J'ai mis à jour le fragment de code javascript de manière à ce qu'il ne puisse pas être lu automatiquement lorsqu'il est chargé sur des appareils mobiles. L'utilisateur doit appuyer sur le bouton de lecture. 

Le son ne peut pas être lu lors du chargement de la page et nécessite au moins une interaction utilisateur (événement tactile) avec la page avant de pouvoir être lue. J'adorerais que l'on me prouve le contraire, alors si quelqu'un sait quelque chose d'autre, éloignez-vous!

Vous pouvez trouver mon exemple de projet ici:

Projet Web: https://github.com/davethomas11/stackoverlow_Q_39625513/tree/master/WebPlayer Hébergé ici -> https: // www.daveanthonythomas.com/remote/so39625513/

Android: https://github.com/davethomas11/stackoverlow_Q_39625513/SoundCloudPlayer

Vérifiez-le et posez-moi des questions sur la mise en œuvre si quelque chose n'est pas clair. Cela vaut pour quiconque lit cette réponse.

La solution est faite nativement en Java. Mais cela pourrait également être fait en HTML et Javascript si c'est ce que vous préférez, car nous utilisons leur API HTTP Rest, la plate-forme n'a pas d'importance.

Cette méthode nous donne un contrôle total sur l’interface utilisateur. Mon interface utilisateur n’est pas la plus belle, mais elle peut être aussi laide ou aussi belle que vous le souhaitez avec ce niveau de contrôle;) ->

SoundCloudPlayer

Je vais expliquer les étapes de base de l'utilisation de l'API Sound Cloud pour accomplir cela. 

Heureusement pour nous, la lecture est très simple. Vous pouvez ignorer toutes les exigences d'authentification. Comme tous les ordinateurs d'extrémité que vous utiliserez, aucune authentification n'est requise.

Tout ce dont vous avez besoin est un identifiant client pour faire vos demandes. Je recommande d'enregistrer une application avec sound cloud, mais vous pouvez utiliser l'identifiant client du lecteur intégré comme je l'ai fait. 

Remarque: le lecteur intégré utilise l'identifiant du client -> cUa40O3Jg3Emvp6Tv4U6ymYYOONNppJ} _ 

La base de cette implémentation est la tracks endpoint: Https://developers.soundcloud.com/docs/api/reference#tracks

Ce point final nous donne presque tout ce dont nous avons besoin:

  • uRL de streaming
  • titre, nom d'artiste
  • ouvrages d'art

Mais il manque un élément: les points de données de la forme d'onde pour afficher la forme d'onde d'identification de la marque SoundCloud. 

L'obtention de ces données nécessite un peu de piratage. Mais les données sont là sous une forme assez pure pour être utilisées.

Si vous examinez la réponse d'un appel pour obtenir le lecteur intégré, vous remarquerez qu'une ressource est chargée dans le code source sous le nom waveform_url. Cette URL renvoie un document Nice json contenant toutes les informations relatives au point d'onde: https://wis.sndcdn.com/sTEoteC5oW3r_m.json

J'ai adapté ma solution pour analyser les données de forme d'onde du lecteur intégré, en les récupérant à partir de cette URL.

Vous remarquerez que j'ai fait une version très grossière. Avec un peu d'huile de coude, cela peut être transformé en quelque chose de gentil, et même unique. Mais les bases sont là pour l’acquérir.

enter image description here

Un autre noeud final que j'ai implémenté dans ma solution est le noeud final de commentaires: https://developers.soundcloud.com/docs/api/reference#comments

Je ne l'ai pas encore ajouté à l'interface utilisateur. Mais le code de l'API devrait éclairer son utilisation.

Le projet Android utilise les bibliothèques suivantes:

Et pour ceux qui ne le connaissent pas, puisqu'il est semi-neuf: - Android DataBinding https://developer.Android.com/topic/libraries/data-binding/index.html

N'hésitez pas à utiliser ma solution comme base, car je l'ai publiée sous la licence GNU. Cela va à tous ceux qui lisent ceci.

J'aimerais également ajouter une solution iOS similaire au référentiel git-hub.

Voici le projet Web sous forme d'extrait: Edit je l'ai mis à jour pour utiliser une image de forme d'onde comme suggéré dans les commentaires plutôt que d'assumer la tâche complexe du rendu d'une forme d'onde. Ce serait super cool si quelqu'un était capable de faire de l'ingénierie inverse du dessin de la toile soundcloud. Le JavaScript est disponible dans cette iframe.

/*!
 * jQuery UI Touch Punch 0.2.3
 *
 * Copyright 2011–2014, Dave Furfero
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * Depends:
 *  jquery.ui.widget.js
 *  jquery.ui.mouse.js
 */
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

function WaveForm(waveformPngUrl) {

	$('.track_waveform').append("<img src=\""+waveformPngUrl+"\" />");
	$('.track_waveform').append("<div class='wvprogress'></div>")

	this.setProgress = function (newProgress) {

		var width = $('.track_waveform').width();
		var progressPoint =  width - ((1 - newProgress) * width);
		$('.wvprogress').css({ width: "" + progressPoint + "px" });

	}
}

var player, mTrack, audio, seekBarInterval, waveForm;
var updatingSeekBar = false;
var clientId = 'cUa40O3Jg3Emvp6Tv4U6ymYYO50NUGpJ';

$(function () {

    SC.initialize({
        client_id: clientId
    });

    player = document.getElementById("SoundCloudPlayer");

    checkQueryURLForTrackId();
    loadTrackEnteredInInput();

    $("form button").button();
});

function loadTrackEnteredInInput() {

    loadTrack(getTrackId());
}

function loadTrack(trackId) {


    SC.get('/tracks/' + trackId).then(function (track) {

        // Inspect for info on track you want:
        console.log(track);
        mTrack = track;

        renderTrack(track);
        streamTrack(track);

        waveForm = new WaveForm(track.waveform_url);

    }, function () {

        alert("Sorry no track found for track id: "+ trackId)
    });
}

function renderTrack(track) {

    $(player).find(".track_artist").text(track.user.permalink);
    $(player).find(".track_title").text(track.title);
    $(player).find(".track_artwork").attr('src', track.artwork_url);
    $(player).find(".track_seek_bar").slider(
        {
            orientation: "horizontal",
            range: "min",
            max: track.duration,
            value: 0,
            change: seek
        });

}

function streamTrack(track) {

    var trackUrl = track.stream_url + "?client_id=" + clientId;

    audio = new Audio(trackUrl);
    console.log(trackUrl);

    if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
        
        // Sorry can not auto play on mobile =_(
        // https://stackoverflow.com/questions/26066062/autoplay-html5-audio-player-on-mobile-browsers
        $(player).find(".track_pause").hide();
        $(player).find(".track_play").fadeIn();
    } else {
        play();
    }
    
}

function play() {

    $(player).find(".track_play").hide();
    $(player).find(".track_pause").fadeIn();

    audio.play();

    seekBarInterval = setInterval(updateSeekBar, 500);
}

function pause() {

    $(player).find(".track_pause").hide();
    $(player).find(".track_play").fadeIn();

    audio.pause();

    clearInterval(seekBarInterval);
}

function seek(event) {

    if (event.originalEvent) {
        audio.currentTime = $(player).find(".track_seek_bar").slider("value") / 1000;
    }
    waveForm.setProgress((audio.currentTime * 1000) / mTrack.duration); 
}

function updateSeekBar() {

    var time = (audio.currentTime * 1000);
    $(player).find(".track_seek_bar").slider("value", time);
}

/**
 * Loads a different track id based on
 * url query
 */
function checkQueryURLForTrackId() {
    var query = getUrlVars();
    if (query.trackId) {
        $('[name=trackId]').val(query.trackId);
    }
}

//https://stackoverflow.com/questions/4656843/jquery-get-querystring-from-url
// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
    var vars = {}, hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars[hash[0]] = hash[1];
    }
    return vars;
}

function getTrackId() {
    return trackId = $('[name=trackId]').val();
}
body {
    font-family: 'Raleway', sans-serif;
}

#SoundCloudPlayer .track_artwork {
    float:left;
    margin-right: 6px;
}

#SoundCloudPlayer .track_artist {
    font-size: small;
    margin-bottom: 4px;
}

#SoundCloudPlayer .track_title {
    margin-top: 0px;
    font-weight: bold;
}

#SoundCloudPlayer .track_control {
    cursor: pointer;
    display: none;
}

#SoundCloudPlayer .track_seek_bar .ui-slider-range { background: orange; }
#SoundCloudPlayer .track_seek_bar .ui-slider-handle { border-color: orange; }

#SoundCloudPlayer .track_waveform {
    width: 100%;
    height: 80px;
    margin-top: 5px;
    margin-bottom: 5px;
    position: relative;
}

#SoundCloudPlayer .track_waveform img {
    
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 0;
}

#SoundCloudPlayer .track_waveform .wvprogress{
    height: 100%;
    position: absolute;
    opacity: 0.25;
    background-color: #ed970e;
    width: 0px;
    z-index: 1;
    left: 0;
    top: 0;
}
<html>
<head>
    <meta name="viewport" content="initial-scale=1, maximum-scale=1">
    <title>SoundCloud API Web Player Demo</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/themes/smoothness/jquery-ui.css" />
    <script src="jquery.ui.touch-punch.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js"></script>
    <script src="https://connect.soundcloud.com/sdk/sdk-3.1.2.js"></script>
    <script src="waveformImage.js"></script>
    <script src="player.js"></script>
    <link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet" />
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
    <link href="style.css" rel="stylesheet" />
</head>
<body>

<form method="get">
    <label for="trackId">Load Track:</label>
    <input name="trackId" type="text" value="271188615" />
    <button>GO</button>
</form>

<section id="SoundCloudPlayer">

    <img class="track_artwork" />
    <p class="track_artist"></p>
    <p class="track_title"></p>
    <i class="material-icons track_play track_control" onClick="play()">play_circle_filled</i>
    <i class="material-icons track_pause track_control" onClick="pause()">pause_circle_filled</i>
    <br style="clear:both"/>
    <div class="track_waveform"></div>
    <div class="track_seek_bar" ></div>
</section>
</body>
</html>

10
Dave Thomas

Mini Player (height = 20) a une apparence et une convivialité identiques pour les ordinateurs de bureau et les mobiles.

<iframe width="100%" height="20" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/271188615&color=ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false"></iframe>
6
Vadim Gulyakin

Vous pouvez définir WebView pour afficher la version de bureau. de site:

WebView view = new WebView(this);
view.getSettings().setUserAgentString("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36");
0
Tomaš Šturo