Soundcloud嵌入式播放器在移动设备上

时间:2016-09-21 19:58:24

标签: html responsive-design 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>

4 个答案:

答案 0 :(得分:11)

我建议不要为播放器使用嵌入式iframe,而是使用SoundCloud's HTTP API

我的回答并未关注任何欺骗嵌入式iframe代码的方法,而不是认为它是移动的。相反,我正在展示如何使用自己的SoundCloud播放器的替代路径。

这样做可以保证:

  • 您可以完全控制您的用户界面
  • 您可以完全控制播放

我已经在Android中构建了一个示例应用程序。假设您在这里寻找Android,因为已发布问题的图像中的状态栏。

根据要求,还有一个可以在移动设备上运行的网络项目。 Web项目正在使用SoundCloud的api JavaScript包装器。

2016年10月20日更新: 我在网络浏览器中对移动设备上的自动播放进行了一些研究。事实证明有很多很好的问题可以回答这个问题。可悲的是,我得出的结论是不可能的。 "Autoplay" HTML5 audio player on mobile browsers我已将javascript代码段更新为现在在加载到移动设备上时无法自动播放。它要求用户按下播放按钮。

音频无法在页面加载时播放,并且在播放之前至少需要与页面进行一次用户交互(触摸事件)。我很想在这方面被证明是错误的,所以如果有人知道其他任何事情就会消失!

  

您可以在此处找到我的示例项目:

     

网络项目:   的 https://github.com/davethomas11/stackoverlow_Q_39625513/tree/master/WebPlayer   托管在这里 - &gt; https://www.daveanthonythomas.com/remote/so39625513/

     

机器人:   的 https://github.com/davethomas11/stackoverlow_Q_39625513/SoundCloudPlayer

检查一下,如果有任何不清楚的地方,请向我询问有关实施的任何问题。任何人都可以阅读这个答案。

解决方案是用Java本地完成的。但它也可以用HTML和Javascript完成,如果这是你喜欢的,因为我们正在使用他们的HTTP Rest API平台并不重要。

完全自定义,这种方式让我们可以完全控制UI。 我的UI并不是最美丽的,但它可以像你想要的那样丑陋或美丽,具有这种控制水平;) - &gt;

SoundCloudPlayer

我将分解使用声音云api实现这一目标的基本步骤。

幸运的是,我们播放非常直接。您可以跳过所有身份验证要求。您将使用的任何端点都不需要身份验证。

您只需要一个客户ID即可发出请求。 我建议使用声音云注册应用程序,但您可以像我一样使用嵌入式播放器的客户端ID。

注意:嵌入式播放器使用客户端ID - &gt; cUa40O3Jg3Emvp6Tv4U6ymYYO50NUGpJ

此实施的基础是曲目端点: https://developers.soundcloud.com/docs/api/reference#tracks

这个端点几乎为我们提供了所需的一切:

  • 流媒体网址
  • 标题,艺术家姓名
  • 艺术品

但是缺少一件事,那就是显示SoundCloud品牌识别波形的波形数据点。

获取此数据的基础知识需要一点点黑客攻击。但是数据是以足够纯粹的形式使用的。

如果您检查调用的响应以获取嵌入式播放器,您将注意到源代码中加载的资源名称为waveform_url。这个url返回一个包含所有波点信息的好的json文档:https://wis.sndcdn.com/sTEoteC5oW3r_m.json

我已经调整了我的解决方案来解析嵌入式播放器中的波形数据,方法是从该网址中检索它。

你会注意到我制作了一个非常粗糙的版本。有了一点点肘部油脂,这可以变成美好的东西,甚至是独一无二的。但是有基础可以获得它。

enter image description here

我在我的解决方案中实现的另一个端点是注释端点:https://developers.soundcloud.com/docs/api/reference#comments

我还没有将它添加到用户界面。但是API代码应该为它的使用提供一些启示。

Android项目使用以下库:

对于那些不熟悉的人,因为它是半新的:   - Android DataBinding https://developer.android.com/topic/libraries/data-binding/index.html

请随意使用我的解决方案作为基础,因为我已经在GNU许可下发布了它。任何阅读此内容的人都会这样做。

我也想考虑在git-hub存储库中添加类似的iOS解决方案。

  

以下是作为代码段的Web项目:   编辑我已将其更新为使用评论中建议的波形图像,而不是承担渲染波形的复杂任务。 如果有人能够对soundcloud画布绘图进行逆向工程,那将会非常酷。该iframe中提供了JavaScript。

&#13;
&#13;
/*!
 * 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();
}
&#13;
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;
}
&#13;
<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;
&#13;
&#13;

答案 1 :(得分:6)

Mini Player(身高= 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>

答案 2 :(得分:3)

使用show_teaser = false作为参数来隐藏叠加层。

答案 3 :(得分:0)

您可以设置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");