web-dev-qa-db-ja.com

モバイル上のSoundcloud組み込みプレーヤー

HTMLページのSoundCloud埋め込みプレーヤーがモバイルデバイスでどのように表示されるかを次に示します。

enter image description here

ユーザーが「ブラウザで聞く」をクリックする必要があり、その後、多くの場合、正常に起動しないため、ユーザーは「一時停止」ボタンをクリックしてもう一度「再生」する必要があるため、かなり面倒です。

モバイルデバイスでも通常の外観にする方法は?

enter image description here


埋め込みコードの例を次に示します。

<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

オーバーレイを非表示にするパラメーターとしてshow_teaser = falseを使用します。

1
Markus

プレーヤーに埋め込みiframeを使用せず、代わりに SoundCloudのHTTP API を使用することをお勧めします。

私の答えは、埋め込まれたiframeコードをだましてモバイルだと思わせない方法に焦点を当てていません。代わりに、私はあなた自身のSoundCloudプレーヤーを作る方法への別の道を示しています。

これを行うと、次のことが保証されます。

  • UIを完全に制御できます
  • 再生を完全に制御できます

私は先に進み、Androidでサンプルアプリケーションを構築しました。投稿された質問の画像のステータスバーのため、ここでAndroidを探していると仮定します。

また、リクエストに応じて、モバイルで動作するWebプロジェクトがあります。 Webプロジェクトは、SoundCloudのapiJavaScriptラッパーを使用しています。

2016年10月20日更新:ウェブブラウザでのモバイルでの自動再生について調査しました。これに答える素晴らしい質問がたくさんあることがわかりました。悲しいことに、私はそれが不可能であるという結論に達しました。 モバイルブラウザでの「自動再生」HTML5オーディオプレーヤー モバイルデバイスに読み込まれたときに自動再生されないようにjavascriptスニペットを更新しました。ユーザーは再生ボタンを押す必要があります。

オーディオはページの読み込み時に再生できません。再生するには、ページとのユーザー操作(タッチイベント)が少なくとも1回必要です。私はこれについて間違っていると証明されたいので、誰かが何か他のものを知っているなら、発砲してください!

私のサンプルプロジェクトはここにあります:

Webプロジェクト:https://github.com/davethomas11/stackoverlow_Q_39625513/tree/master/WebPlayerここでホスト->- https://www.daveanthonythomas.com/remote/so39625513/

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

それをチェックして、何か明確でないことがあれば、実装に関する質問をしてください。これは、この答えを読んでいる人なら誰にでも当てはまります。

ソリューションはJavaでネイティブに実行されます。ただし、HTTP Rest APIを使用しているため、プラットフォームが重要ではないため、HTMLとJavascriptで実行することもできます。

完全にカスタム化することで、この方法でUIを完全に制御できます。私のUIは最も美しいわけではありませんが、このレベルのコントロールを使用すると、必要に応じて醜いものや美しいものにすることができます;)->

SoundCloudPlayer

これを達成するためにsoundcloudのAPIを使用する基本的な手順を説明します。

幸いなことに、再生は非常に簡単です。すべての認証要件をスキップできます。使用するエンドポイントは認証を必要としないためです。

必要なのは、リクエストを行うためのクライアントIDだけです。 アプリをSound Cloudに登録することをお勧めしますが、埋め込みプレーヤーのクライアントIDは私と同じように使用できます。

注:組み込みプレーヤーはクライアントIDを使用します-> cUa40O3Jg3Emvp6Tv4U6ymYYO50NUGpJ

この実装の基本は、tracksエンドポイントです: https://developers.soundcloud.com/docs/api/reference#tracks

このエンドポイントは、必要なほとんどすべてのものを提供します。

  • ストリーミングURL
  • タイトル、アーティスト名
  • アートワーク

しかし、欠けているものが1つあります。それは、SoundCloudのブランドを識別する波形を表示するための波形データポイントです。

このデータを取得するための基本は、少しハッキングする必要があります。しかし、データは使用するのに十分純粋な形でそこにあります。

埋め込みプレーヤーを取得するために呼び出しの応答を調べると、waveform_urlという名前でソースコードにリソースがロードされていることがわかります。このURLは、すべてのウェーブポイント情報を含むNice jsonドキュメントを返します: https://wis.sndcdn.com/sTEoteC5oW3r_m.json

そのURLから波形データを取得することにより、埋め込みプレーヤーからの波形データを解析するようにソリューションを適合させました。

あなたは私が非常に粗雑なバージョンを作ったことに気付くでしょう。少しの肘のグリースで、これは素晴らしいもの、さらにはユニークなものに変えることができます。しかし、それを取得するための基本はそこにあります。

enter image description here

私がソリューションに実装したもう1つのエンドポイントは、コメントエンドポイントです: https://developers.soundcloud.com/docs/api/reference#comments

まだUIに追加していません。しかし、APIコードは、その使用法に光を当てる必要があります。

Androidプロジェクトは、次のライブラリを使用します。

そして、慣れていない人のために、それは半新しいので:-Android DataBinding https://developer.Android.com/topic/libraries/data-binding/index.html

GNUライセンスの下でリリースしたので、私のソリューションをベースとして自由に使用してください。これを読んでいる人なら誰でもそうです。

同様のiOSソリューションをgit-hubリポジトリに追加することも検討したいと思います。

スニペットとしてのWebプロジェクトは次のとおりです。Editの複雑なタスクを実行するのではなく、コメントで提案されている波形画像を使用するように更新しました。波形のレンダリング。 誰かがsoundcloudキャンバスの描画をリバースエンジニアリングできれば、とてもクールです。 JavaScriptはその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>
13
Dave Thomas

ミニプレーヤー(高さ= 20)は、デスクトップとモバイルで同様のルックアンドフィールを備えています。

<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

WebViewを設定してデスクトップバージョンを表示できます。サイトの:

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");
1
Tomaš Šturo