mirror of
https://github.com/SuperBFG7/ympd
synced 2024-12-23 09:30:26 +00:00
various fixups
This commit is contained in:
parent
c692feb111
commit
d194c8439a
138
htdocs/css/slider.css
Normal file
138
htdocs/css/slider.css
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/*!
|
||||||
|
* Slider for Bootstrap
|
||||||
|
*
|
||||||
|
* Copyright 2012 Stefan Petre
|
||||||
|
* Licensed under the Apache License v2.0
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.slider {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.slider.slider-horizontal {
|
||||||
|
width: 210px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
.slider.slider-horizontal .slider-track {
|
||||||
|
height: 10px;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: -5px;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.slider.slider-horizontal .slider-selection {
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.slider.slider-horizontal .slider-handle {
|
||||||
|
margin-left: -10px;
|
||||||
|
margin-top: -5px;
|
||||||
|
}
|
||||||
|
.slider.slider-horizontal .slider-handle.triangle {
|
||||||
|
border-width: 0 10px 10px 10px;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-bottom-color: #0480be;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.slider.slider-vertical {
|
||||||
|
height: 210px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
.slider.slider-vertical .slider-track {
|
||||||
|
width: 10px;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: -5px;
|
||||||
|
left: 50%;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.slider.slider-vertical .slider-selection {
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.slider.slider-vertical .slider-handle {
|
||||||
|
margin-left: -5px;
|
||||||
|
margin-top: -10px;
|
||||||
|
}
|
||||||
|
.slider.slider-vertical .slider-handle.triangle {
|
||||||
|
border-width: 10px 0 10px 10px;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
border-left-color: #0480be;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.slider input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.slider .tooltip-inner {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.slider-track {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
|
||||||
|
background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||||
|
background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||||
|
background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
|
||||||
|
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.slider-selection {
|
||||||
|
position: absolute;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));
|
||||||
|
background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||||
|
background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||||
|
background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);
|
||||||
|
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.slider-handle {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #0e90d2;
|
||||||
|
background-image: -moz-linear-gradient(top, #149bdf, #0480be);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
|
||||||
|
background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
|
||||||
|
background-image: -o-linear-gradient(top, #149bdf, #0480be);
|
||||||
|
background-image: linear-gradient(to bottom, #149bdf, #0480be);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
|
||||||
|
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||||
|
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||||
|
opacity: 0.8;
|
||||||
|
border: 0px solid transparent;
|
||||||
|
}
|
||||||
|
.slider-handle.round {
|
||||||
|
-webkit-border-radius: 20px;
|
||||||
|
-moz-border-radius: 20px;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
.slider-handle.triangle {
|
||||||
|
background: transparent none;
|
||||||
|
}
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<!-- Custom styles for this template -->
|
<!-- Custom styles for this template -->
|
||||||
<link href="css/starter-template.css" rel="stylesheet">
|
<link href="css/starter-template.css" rel="stylesheet">
|
||||||
|
<link href="css/slider.css" rel="stylesheet">
|
||||||
|
|
||||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
@ -53,18 +54,19 @@
|
|||||||
<div class="btn-toolbar navbar-btn navbar-right" role="toolbar">
|
<div class="btn-toolbar navbar-btn navbar-right" role="toolbar">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-default">
|
<button type="button" class="btn btn-default">
|
||||||
<span class="glyphicon glyphicon-backward"></span>
|
<span class="glyphicon glyphicon-backward" onclick="socket.send('MPD_API_SET_NEXT')"></span>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default" data-toggle="button">
|
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_PAUSE')">
|
||||||
<span class="glyphicon glyphicon-pause"></span>
|
<span id="play-icon" class="glyphicon glyphicon-pause"></span>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-default" onclick="test();">
|
<button type="button" class="btn btn-default" onclick="socket.send('MPD_API_SET_PREV')">
|
||||||
<span class="glyphicon glyphicon-forward"></span>
|
<span class="glyphicon glyphicon-forward"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button id="volume" type="button" class="btn btn-default" data-toggle="button">
|
<button type="button" class="btn btn-toolbar btn-default">
|
||||||
<span id="volume-icon" class="glyphicon glyphicon-volume-off"></span>
|
<span id="volume-icon" class="glyphicon glyphicon-volume-up"></span>
|
||||||
|
<input type="text" class="span2" value="0" data-slider-min="0" data-slider-max="100" data-slider-step="5" id="volumeslider" data-slider-tooltip="hide">
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -74,7 +76,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="progress progress-striped active">
|
<div class="progress progress-striped active">
|
||||||
<div class="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 45%">
|
<div id="progressbar" class="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 45%">
|
||||||
<span class="sr-only">60% Complete</span>
|
<span class="sr-only">60% Complete</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -86,34 +88,16 @@
|
|||||||
<div class="panel-heading">Playlist</div>
|
<div class="panel-heading">Playlist</div>
|
||||||
|
|
||||||
<!-- Table -->
|
<!-- Table -->
|
||||||
<table class="table">
|
<table id="salamisandwich" class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th>Track</th>
|
<th>Track</th>
|
||||||
<th>Last Name</th>
|
<th>Title</th>
|
||||||
<th>Username</th>
|
<th>Duration</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
|
||||||
<td>1</td>
|
|
||||||
<td>Mark</td>
|
|
||||||
<td>Otto</td>
|
|
||||||
<td>@mdo</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td>Jacob</td>
|
|
||||||
<td>Thornton</td>
|
|
||||||
<td>@fat</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>3</td>
|
|
||||||
<td>Larry</td>
|
|
||||||
<td>the Bird</td>
|
|
||||||
<td>@twitter</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -125,8 +109,9 @@
|
|||||||
<!-- Bootstrap core JavaScript
|
<!-- Bootstrap core JavaScript
|
||||||
================================================== -->
|
================================================== -->
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
|
<script src="js/jquery-1.10.2.min.js"></script>
|
||||||
<script src="js/bootstrap.min.js"></script>
|
<script src="js/bootstrap.min.js"></script>
|
||||||
|
<script src="js/bootstrap-slider.js"></script>
|
||||||
<script src="js/mpd.js"></script>
|
<script src="js/mpd.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
388
htdocs/js/bootstrap-slider.js
vendored
Normal file
388
htdocs/js/bootstrap-slider.js
vendored
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
/* =========================================================
|
||||||
|
* bootstrap-slider.js v2.0.0
|
||||||
|
* http://www.eyecon.ro/bootstrap-slider
|
||||||
|
* =========================================================
|
||||||
|
* Copyright 2012 Stefan Petre
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ========================================================= */
|
||||||
|
|
||||||
|
!function( $ ) {
|
||||||
|
|
||||||
|
var Slider = function(element, options) {
|
||||||
|
this.element = $(element);
|
||||||
|
this.picker = $('<div class="slider">'+
|
||||||
|
'<div class="slider-track">'+
|
||||||
|
'<div class="slider-selection"></div>'+
|
||||||
|
'<div class="slider-handle"></div>'+
|
||||||
|
'<div class="slider-handle"></div>'+
|
||||||
|
'</div>'+
|
||||||
|
'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'+
|
||||||
|
'</div>')
|
||||||
|
.insertBefore(this.element)
|
||||||
|
.append(this.element);
|
||||||
|
this.id = this.element.data('slider-id')||options.id;
|
||||||
|
if (this.id) {
|
||||||
|
this.picker[0].id = this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof Modernizr !== 'undefined' && Modernizr.touch) {
|
||||||
|
this.touchCapable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tooltip = this.element.data('slider-tooltip')||options.tooltip;
|
||||||
|
|
||||||
|
this.tooltip = this.picker.find('.tooltip');
|
||||||
|
this.tooltipInner = this.tooltip.find('div.tooltip-inner');
|
||||||
|
|
||||||
|
this.orientation = this.element.data('slider-orientation')||options.orientation;
|
||||||
|
switch(this.orientation) {
|
||||||
|
case 'vertical':
|
||||||
|
this.picker.addClass('slider-vertical');
|
||||||
|
this.stylePos = 'top';
|
||||||
|
this.mousePos = 'pageY';
|
||||||
|
this.sizePos = 'offsetHeight';
|
||||||
|
this.tooltip.addClass('right')[0].style.left = '100%';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.picker
|
||||||
|
.addClass('slider-horizontal')
|
||||||
|
.css('width', this.element.outerWidth());
|
||||||
|
this.orientation = 'horizontal';
|
||||||
|
this.stylePos = 'left';
|
||||||
|
this.mousePos = 'pageX';
|
||||||
|
this.sizePos = 'offsetWidth';
|
||||||
|
this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.min = this.element.data('slider-min')||options.min;
|
||||||
|
this.max = this.element.data('slider-max')||options.max;
|
||||||
|
this.step = this.element.data('slider-step')||options.step;
|
||||||
|
this.value = this.element.data('slider-value')||options.value;
|
||||||
|
if (this.value[1]) {
|
||||||
|
this.range = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selection = this.element.data('slider-selection')||options.selection;
|
||||||
|
this.selectionEl = this.picker.find('.slider-selection');
|
||||||
|
if (this.selection === 'none') {
|
||||||
|
this.selectionEl.addClass('hide');
|
||||||
|
}
|
||||||
|
this.selectionElStyle = this.selectionEl[0].style;
|
||||||
|
|
||||||
|
|
||||||
|
this.handle1 = this.picker.find('.slider-handle:first');
|
||||||
|
this.handle1Stype = this.handle1[0].style;
|
||||||
|
this.handle2 = this.picker.find('.slider-handle:last');
|
||||||
|
this.handle2Stype = this.handle2[0].style;
|
||||||
|
|
||||||
|
var handle = this.element.data('slider-handle')||options.handle;
|
||||||
|
switch(handle) {
|
||||||
|
case 'round':
|
||||||
|
this.handle1.addClass('round');
|
||||||
|
this.handle2.addClass('round');
|
||||||
|
break
|
||||||
|
case 'triangle':
|
||||||
|
this.handle1.addClass('triangle');
|
||||||
|
this.handle2.addClass('triangle');
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.range) {
|
||||||
|
this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0]));
|
||||||
|
this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1]));
|
||||||
|
} else {
|
||||||
|
this.value = [ Math.max(this.min, Math.min(this.max, this.value))];
|
||||||
|
this.handle2.addClass('hide');
|
||||||
|
if (this.selection == 'after') {
|
||||||
|
this.value[1] = this.max;
|
||||||
|
} else {
|
||||||
|
this.value[1] = this.min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.diff = this.max - this.min;
|
||||||
|
this.percentage = [
|
||||||
|
(this.value[0]-this.min)*100/this.diff,
|
||||||
|
(this.value[1]-this.min)*100/this.diff,
|
||||||
|
this.step*100/this.diff
|
||||||
|
];
|
||||||
|
|
||||||
|
this.offset = this.picker.offset();
|
||||||
|
this.size = this.picker[0][this.sizePos];
|
||||||
|
|
||||||
|
this.formater = options.formater;
|
||||||
|
|
||||||
|
this.layout();
|
||||||
|
|
||||||
|
if (this.touchCapable) {
|
||||||
|
// Touch: Bind touch events:
|
||||||
|
this.picker.on({
|
||||||
|
touchstart: $.proxy(this.mousedown, this)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.picker.on({
|
||||||
|
mousedown: $.proxy(this.mousedown, this)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooltip === 'show') {
|
||||||
|
this.picker.on({
|
||||||
|
mouseenter: $.proxy(this.showTooltip, this),
|
||||||
|
mouseleave: $.proxy(this.hideTooltip, this)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.tooltip.addClass('hide');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Slider.prototype = {
|
||||||
|
constructor: Slider,
|
||||||
|
|
||||||
|
over: false,
|
||||||
|
inDrag: false,
|
||||||
|
|
||||||
|
showTooltip: function(){
|
||||||
|
this.tooltip.addClass('in');
|
||||||
|
//var left = Math.round(this.percent*this.width);
|
||||||
|
//this.tooltip.css('left', left - this.tooltip.outerWidth()/2);
|
||||||
|
this.over = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
hideTooltip: function(){
|
||||||
|
if (this.inDrag === false) {
|
||||||
|
this.tooltip.removeClass('in');
|
||||||
|
}
|
||||||
|
this.over = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
layout: function(){
|
||||||
|
this.handle1Stype[this.stylePos] = this.percentage[0]+'%';
|
||||||
|
this.handle2Stype[this.stylePos] = this.percentage[1]+'%';
|
||||||
|
if (this.orientation == 'vertical') {
|
||||||
|
this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%';
|
||||||
|
this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%';
|
||||||
|
} else {
|
||||||
|
this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%';
|
||||||
|
this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%';
|
||||||
|
}
|
||||||
|
if (this.range) {
|
||||||
|
this.tooltipInner.text(
|
||||||
|
this.formater(this.value[0]) +
|
||||||
|
' : ' +
|
||||||
|
this.formater(this.value[1])
|
||||||
|
);
|
||||||
|
this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px';
|
||||||
|
} else {
|
||||||
|
this.tooltipInner.text(
|
||||||
|
this.formater(this.value[0])
|
||||||
|
);
|
||||||
|
this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mousedown: function(ev) {
|
||||||
|
|
||||||
|
// Touch: Get the original event:
|
||||||
|
if (this.touchCapable && ev.type === 'touchstart') {
|
||||||
|
ev = ev.originalEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.offset = this.picker.offset();
|
||||||
|
this.size = this.picker[0][this.sizePos];
|
||||||
|
|
||||||
|
var percentage = this.getPercentage(ev);
|
||||||
|
|
||||||
|
if (this.range) {
|
||||||
|
var diff1 = Math.abs(this.percentage[0] - percentage);
|
||||||
|
var diff2 = Math.abs(this.percentage[1] - percentage);
|
||||||
|
this.dragged = (diff1 < diff2) ? 0 : 1;
|
||||||
|
} else {
|
||||||
|
this.dragged = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.percentage[this.dragged] = percentage;
|
||||||
|
this.layout();
|
||||||
|
|
||||||
|
if (this.touchCapable) {
|
||||||
|
// Touch: Bind touch events:
|
||||||
|
$(document).on({
|
||||||
|
touchmove: $.proxy(this.mousemove, this),
|
||||||
|
touchend: $.proxy(this.mouseup, this)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$(document).on({
|
||||||
|
mousemove: $.proxy(this.mousemove, this),
|
||||||
|
mouseup: $.proxy(this.mouseup, this)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inDrag = true;
|
||||||
|
var val = this.calculateValue();
|
||||||
|
this.element.trigger({
|
||||||
|
type: 'slideStart',
|
||||||
|
value: val
|
||||||
|
}).trigger({
|
||||||
|
type: 'slide',
|
||||||
|
value: val
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
mousemove: function(ev) {
|
||||||
|
|
||||||
|
// Touch: Get the original event:
|
||||||
|
if (this.touchCapable && ev.type === 'touchmove') {
|
||||||
|
ev = ev.originalEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var percentage = this.getPercentage(ev);
|
||||||
|
if (this.range) {
|
||||||
|
if (this.dragged === 0 && this.percentage[1] < percentage) {
|
||||||
|
this.percentage[0] = this.percentage[1];
|
||||||
|
this.dragged = 1;
|
||||||
|
} else if (this.dragged === 1 && this.percentage[0] > percentage) {
|
||||||
|
this.percentage[1] = this.percentage[0];
|
||||||
|
this.dragged = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.percentage[this.dragged] = percentage;
|
||||||
|
this.layout();
|
||||||
|
var val = this.calculateValue();
|
||||||
|
this.element
|
||||||
|
.trigger({
|
||||||
|
type: 'slide',
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
.data('value', val)
|
||||||
|
.prop('value', val);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
mouseup: function(ev) {
|
||||||
|
if (this.touchCapable) {
|
||||||
|
// Touch: Bind touch events:
|
||||||
|
$(document).off({
|
||||||
|
touchmove: this.mousemove,
|
||||||
|
touchend: this.mouseup
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$(document).off({
|
||||||
|
mousemove: this.mousemove,
|
||||||
|
mouseup: this.mouseup
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inDrag = false;
|
||||||
|
if (this.over == false) {
|
||||||
|
this.hideTooltip();
|
||||||
|
}
|
||||||
|
this.element;
|
||||||
|
var val = this.calculateValue();
|
||||||
|
this.element
|
||||||
|
.trigger({
|
||||||
|
type: 'slideStop',
|
||||||
|
value: val
|
||||||
|
})
|
||||||
|
.data('value', val)
|
||||||
|
.prop('value', val);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
calculateValue: function() {
|
||||||
|
var val;
|
||||||
|
if (this.range) {
|
||||||
|
val = [
|
||||||
|
(this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step),
|
||||||
|
(this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step)
|
||||||
|
];
|
||||||
|
this.value = val;
|
||||||
|
} else {
|
||||||
|
val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step);
|
||||||
|
this.value = [val, this.value[1]];
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
},
|
||||||
|
|
||||||
|
getPercentage: function(ev) {
|
||||||
|
if (this.touchCapable) {
|
||||||
|
ev = ev.touches[0];
|
||||||
|
}
|
||||||
|
var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size;
|
||||||
|
percentage = Math.round(percentage/this.percentage[2])*this.percentage[2];
|
||||||
|
return Math.max(0, Math.min(100, percentage));
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue: function() {
|
||||||
|
if (this.range) {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
return this.value[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
setValue: function(val) {
|
||||||
|
this.value = val;
|
||||||
|
|
||||||
|
if (this.range) {
|
||||||
|
this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0]));
|
||||||
|
this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1]));
|
||||||
|
} else {
|
||||||
|
this.value = [ Math.max(this.min, Math.min(this.max, this.value))];
|
||||||
|
this.handle2.addClass('hide');
|
||||||
|
if (this.selection == 'after') {
|
||||||
|
this.value[1] = this.max;
|
||||||
|
} else {
|
||||||
|
this.value[1] = this.min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.diff = this.max - this.min;
|
||||||
|
this.percentage = [
|
||||||
|
(this.value[0]-this.min)*100/this.diff,
|
||||||
|
(this.value[1]-this.min)*100/this.diff,
|
||||||
|
this.step*100/this.diff
|
||||||
|
];
|
||||||
|
this.layout();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.slider = function ( option, val ) {
|
||||||
|
return this.each(function () {
|
||||||
|
var $this = $(this),
|
||||||
|
data = $this.data('slider'),
|
||||||
|
options = typeof option === 'object' && option;
|
||||||
|
if (!data) {
|
||||||
|
$this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options))));
|
||||||
|
}
|
||||||
|
if (typeof option == 'string') {
|
||||||
|
data[option](val);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.slider.defaults = {
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
step: 1,
|
||||||
|
orientation: 'horizontal',
|
||||||
|
value: 5,
|
||||||
|
selection: 'before',
|
||||||
|
tooltip: 'show',
|
||||||
|
handle: 'round',
|
||||||
|
formater: function(value) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.slider.Constructor = Slider;
|
||||||
|
|
||||||
|
}( window.jQuery );
|
6
htdocs/js/jquery-1.10.2.min.js
vendored
Normal file
6
htdocs/js/jquery-1.10.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -6,16 +6,42 @@ if (typeof MozWebSocket != "undefined") {
|
|||||||
socket = new WebSocket(get_appropriate_ws_url(), "ympd-client");
|
socket = new WebSocket(get_appropriate_ws_url(), "ympd-client");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
socket.onopen = function() {
|
socket.onopen = function() {
|
||||||
console.log("Connected");
|
console.log("Connected");
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.onmessage =function got_packet(msg) {
|
socket.onmessage =function got_packet(msg) {
|
||||||
console.log(msg.data);
|
console.log(msg.data);
|
||||||
}
|
var obj = JSON.parse(msg.data);
|
||||||
|
switch (obj.type) {
|
||||||
|
case "playlist":
|
||||||
|
for (var song in obj.data) {
|
||||||
|
var minutes = Math.floor(obj.data[song].duration / 60);
|
||||||
|
var seconds = obj.data[song].duration - minutes * 60;
|
||||||
|
|
||||||
|
$('#salamisandwich tr:last').after(
|
||||||
|
"<tr id=\"playlist_" + obj.data[song].id + "\"><td>" + obj.data[song].id + "</td>" +
|
||||||
|
"<td>"+ obj.data[song].uri +"</td>" +
|
||||||
|
"<td>"+ obj.data[song].title.replace(/%07/g, '"') +"</td>" +
|
||||||
|
"<td>"+ minutes + ":" + (seconds < 10 ? '0' : '') + seconds +"</td></tr>");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "state":
|
||||||
|
$('#volumeslider').slider('setValue', obj.data.volume)
|
||||||
|
var progress = Math.floor(100*obj.data.elapsedTime/obj.data.totalTime) + "%";
|
||||||
|
$('#progressbar').width(progress);
|
||||||
|
$('#playlist_'+obj.data.currentsongid).addClass('active');
|
||||||
|
updatePlayIcon(obj.data.state);
|
||||||
|
updateVolumeIcon(obj.data.volume);
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
alert("Sie bleiben leider dumm");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
socket.onclose = function(){
|
socket.onclose = function(){
|
||||||
console.log("Disconnected");
|
console.log("Disconnected");
|
||||||
|
|
||||||
@ -24,6 +50,10 @@ try {
|
|||||||
alert('<p>Error' + exception);
|
alert('<p>Error' + exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$('#volumeslider').slider().on('slide', function(event) {
|
||||||
|
socket.send("MPD_API_SET_VOLUME,"+event.value);
|
||||||
|
});
|
||||||
|
|
||||||
function get_appropriate_ws_url()
|
function get_appropriate_ws_url()
|
||||||
{
|
{
|
||||||
var pcol;
|
var pcol;
|
||||||
@ -48,20 +78,42 @@ function get_appropriate_ws_url()
|
|||||||
return pcol + u[0];
|
return pcol + u[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateVolumeIcon = function(mute)
|
var updateVolumeIcon = function(volume)
|
||||||
{
|
{
|
||||||
$("#volume-icon").removeClass("glyphicon-volume-off");
|
$("#volume-icon").removeClass("glyphicon-volume-off");
|
||||||
$("#volume-icon").removeClass("glyphicon-volume-up");
|
$("#volume-icon").removeClass("glyphicon-volume-up");
|
||||||
|
$("#volume-icon").removeClass("glyphicon-volume-down");
|
||||||
|
|
||||||
if(mute) {
|
if(volume == 0) {
|
||||||
$("#volume-icon").addClass("glyphicon-volume-off");
|
$("#volume-icon").addClass("glyphicon-volume-off");
|
||||||
$("#volume").button('toggle')
|
} else if (volume < 50) {
|
||||||
|
$("#volume-icon").addClass("glyphicon-volume-down");
|
||||||
} else {
|
} else {
|
||||||
$("#volume-icon").addClass("glyphicon-volume-up");
|
$("#volume-icon").addClass("glyphicon-volume-up");
|
||||||
$("#volume").button('reset')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var updatePlayIcon = function(state)
|
||||||
|
{
|
||||||
|
$("#play-icon").removeClass("glyphicon-play");
|
||||||
|
$("#play-icon").removeClass("glyphicon-pause");
|
||||||
|
$("#play-icon").removeClass("glyphicon-stop");
|
||||||
|
|
||||||
|
if(state == 1) {
|
||||||
|
$("#play-icon").addClass("glyphicon-stop");
|
||||||
|
} else if(state == 2) {
|
||||||
|
$("#play-icon").addClass("glyphicon-pause");
|
||||||
|
} else {
|
||||||
|
$("#play-icon").addClass("glyphicon-play");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
socket.send("MPD_API_GET_PLAYLIST");
|
||||||
|
socket.send("MPD_API_GET_STATE");
|
||||||
|
}
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
socket.send("MPD_API_GET_PLAYLIST");
|
socket.send("MPD_API_GET_PLAYLIST");
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,13 @@ struct serveable {
|
|||||||
static const struct serveable whitelist[] = {
|
static const struct serveable whitelist[] = {
|
||||||
{ "/css/bootstrap.css", "text/css" },
|
{ "/css/bootstrap.css", "text/css" },
|
||||||
{ "/css/starter-template.css", "text/css" },
|
{ "/css/starter-template.css", "text/css" },
|
||||||
|
{ "/css/slider.css", "text/css" },
|
||||||
|
|
||||||
{ "/js/bootstrap.min.js", "text/javascript" },
|
{ "/js/bootstrap.min.js", "text/javascript" },
|
||||||
{ "/js/mpd.js", "text/javascript" },
|
{ "/js/mpd.js", "text/javascript" },
|
||||||
|
{ "/js/jquery-1.10.2.min.js", "text/javascript" },
|
||||||
|
{ "/js/bootstrap-slider.js", "text/javascript" },
|
||||||
|
|
||||||
{ "/fonts/glyphicons-halflings-regular.woff", "application/x-font-woff"},
|
{ "/fonts/glyphicons-halflings-regular.woff", "application/x-font-woff"},
|
||||||
{ "/fonts/glyphicons-halflings-regular.svg", "image/svg+xml"},
|
{ "/fonts/glyphicons-halflings-regular.svg", "image/svg+xml"},
|
||||||
{ "/fonts/glyphicons-halflings-regular.ttf", "application/x-font-ttf"},
|
{ "/fonts/glyphicons-halflings-regular.ttf", "application/x-font-ttf"},
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "http_server.h"
|
#include "http_server.h"
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
|
|
||||||
static struct libwebsocket_protocols protocols[] = {
|
struct libwebsocket_protocols protocols[] = {
|
||||||
/* first protocol must always be HTTP handler */
|
/* first protocol must always be HTTP handler */
|
||||||
{
|
{
|
||||||
"http-only", /* name */
|
"http-only", /* name */
|
||||||
@ -40,6 +40,7 @@ int main(int argc, char **argv)
|
|||||||
const char *iface = NULL;
|
const char *iface = NULL;
|
||||||
struct lws_context_creation_info info;
|
struct lws_context_creation_info info;
|
||||||
unsigned int oldus = 0;
|
unsigned int oldus = 0;
|
||||||
|
protocol_array = protocols;
|
||||||
|
|
||||||
atexit(bye);
|
atexit(bye);
|
||||||
memset(&info, 0, sizeof info);
|
memset(&info, 0, sizeof info);
|
||||||
|
126
src/mpd_client.c
126
src/mpd_client.c
@ -13,9 +13,12 @@
|
|||||||
|
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
|
|
||||||
|
#define MAX_SIZE 9000*10
|
||||||
|
|
||||||
struct mpd_connection *conn = NULL;
|
struct mpd_connection *conn = NULL;
|
||||||
enum mpd_conn_states mpd_conn_state = MPD_DISCONNECTED;
|
enum mpd_conn_states mpd_conn_state = MPD_DISCONNECTED;
|
||||||
enum mpd_state mpd_play_state = MPD_STATE_UNKNOWN;
|
enum mpd_state mpd_play_state = MPD_STATE_UNKNOWN;
|
||||||
|
static int global_send;
|
||||||
|
|
||||||
callback_ympd(struct libwebsocket_context *context,
|
callback_ympd(struct libwebsocket_context *context,
|
||||||
struct libwebsocket *wsi,
|
struct libwebsocket *wsi,
|
||||||
@ -23,12 +26,18 @@ callback_ympd(struct libwebsocket_context *context,
|
|||||||
void *user, void *in, size_t len)
|
void *user, void *in, size_t len)
|
||||||
{
|
{
|
||||||
int n, m;
|
int n, m;
|
||||||
/*unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
|
char *buf = NULL, *p;
|
||||||
LWS_SEND_BUFFER_POST_PADDING];*/
|
|
||||||
char *buf;
|
|
||||||
struct per_session_data__ympd *pss = (struct per_session_data__ympd *)user;
|
struct per_session_data__ympd *pss = (struct per_session_data__ympd *)user;
|
||||||
|
|
||||||
//memset(buf, 0, sizeof(buf));
|
//if(global_send || (pss != NULL && pss->do_send))
|
||||||
|
//{
|
||||||
|
buf = (char *)malloc(MAX_SIZE + LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING);
|
||||||
|
|
||||||
|
if(buf == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
|
||||||
|
//}
|
||||||
|
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case LWS_CALLBACK_ESTABLISHED:
|
case LWS_CALLBACK_ESTABLISHED:
|
||||||
@ -37,22 +46,24 @@ callback_ympd(struct libwebsocket_context *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||||
|
|
||||||
if(pss->do_send & DO_SEND_STATE)
|
if(pss->do_send & DO_SEND_STATE)
|
||||||
n = mpd_put_state(buf);
|
{
|
||||||
|
n = mpd_put_state(p);
|
||||||
|
pss->do_send &= ~DO_SEND_STATE;
|
||||||
|
}
|
||||||
else if(pss->do_send & DO_SEND_PLAYLIST)
|
else if(pss->do_send & DO_SEND_PLAYLIST)
|
||||||
{
|
{
|
||||||
printf("Before buf is %ud\n",buf);
|
n = mpd_put_playlist(p);
|
||||||
n = mpd_put_playlist(&buf);
|
|
||||||
printf("n is %d, buf is %ud\n", n, buf);
|
|
||||||
pss->do_send &= ~DO_SEND_PLAYLIST;
|
pss->do_send &= ~DO_SEND_PLAYLIST;
|
||||||
}
|
}
|
||||||
else if(pss->do_send & DO_SEND_TRACK_INFO)
|
else if(pss->do_send & DO_SEND_TRACK_INFO)
|
||||||
n = mpd_put_current_song(buf);
|
n = mpd_put_current_song(p);
|
||||||
else
|
else
|
||||||
return 0;
|
{
|
||||||
|
n = mpd_put_state(p);
|
||||||
|
}
|
||||||
|
|
||||||
m = libwebsocket_write(wsi, buf, n, LWS_WRITE_TEXT);
|
m = libwebsocket_write(wsi, p, n, LWS_WRITE_TEXT);
|
||||||
if (m < n) {
|
if (m < n) {
|
||||||
lwsl_err("ERROR %d writing to socket\n", n);
|
lwsl_err("ERROR %d writing to socket\n", n);
|
||||||
return -1;
|
return -1;
|
||||||
@ -60,10 +71,39 @@ callback_ympd(struct libwebsocket_context *context,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LWS_CALLBACK_RECEIVE:
|
case LWS_CALLBACK_RECEIVE:
|
||||||
|
printf("Got %s\n", (char *)in);
|
||||||
|
|
||||||
if(!strcmp((const char *)in, MPD_API_GET_STATE))
|
if(!strcmp((const char *)in, MPD_API_GET_STATE))
|
||||||
pss->do_send |= DO_SEND_STATE;
|
pss->do_send |= DO_SEND_STATE;
|
||||||
if(!strcmp((const char *)in, MPD_API_GET_PLAYLIST))
|
else if(!strcmp((const char *)in, MPD_API_GET_PLAYLIST))
|
||||||
pss->do_send |= DO_SEND_PLAYLIST;
|
pss->do_send |= DO_SEND_PLAYLIST;
|
||||||
|
else if(!strcmp((const char *)in, MPD_API_SET_PAUSE))
|
||||||
|
{
|
||||||
|
mpd_send_toggle_pause(conn);
|
||||||
|
mpd_response_finish(conn);
|
||||||
|
}
|
||||||
|
else if(!strcmp((const char *)in, MPD_API_SET_PREV))
|
||||||
|
{
|
||||||
|
mpd_send_previous(conn);
|
||||||
|
mpd_response_finish(conn);
|
||||||
|
}
|
||||||
|
else if(!strcmp((const char *)in, MPD_API_SET_NEXT))
|
||||||
|
{
|
||||||
|
mpd_send_next(conn);
|
||||||
|
mpd_response_finish(conn);
|
||||||
|
}
|
||||||
|
else if(!strncmp((const char *)in, MPD_API_SET_VOLUME, sizeof(MPD_API_SET_VOLUME)-1))
|
||||||
|
{
|
||||||
|
unsigned int volume;
|
||||||
|
if(sscanf(in, "MPD_API_SET_VOLUME,%ud", &volume) && volume < 100)
|
||||||
|
{
|
||||||
|
printf("Setting volume to %d\n", volume);
|
||||||
|
mpd_run_set_volume(conn, volume);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
@ -89,7 +129,7 @@ void mpd_loop()
|
|||||||
case MPD_DISCONNECTED:
|
case MPD_DISCONNECTED:
|
||||||
/* Try to connect */
|
/* Try to connect */
|
||||||
|
|
||||||
conn = mpd_connection_new("127.0.0.1", 6600, 3000);
|
conn = mpd_connection_new("10.23.44.2", 6600, 3000);
|
||||||
if (conn == NULL) {
|
if (conn == NULL) {
|
||||||
lwsl_err("%s", "Out of memory");
|
lwsl_err("%s", "Out of memory");
|
||||||
mpd_conn_state = MPD_FAILURE;
|
mpd_conn_state = MPD_FAILURE;
|
||||||
@ -119,9 +159,19 @@ void mpd_loop()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* encode_string(const char *str)
|
||||||
|
{
|
||||||
|
char *ptr = (char *)str;
|
||||||
|
while(*ptr++ != '\0')
|
||||||
|
if(*ptr=='"')
|
||||||
|
*ptr=' ';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
int mpd_put_state(char* buffer)
|
int mpd_put_state(char* buffer)
|
||||||
{
|
{
|
||||||
struct mpd_status *status;
|
struct mpd_status *status;
|
||||||
|
int len;
|
||||||
|
|
||||||
status = mpd_run_status(conn);
|
status = mpd_run_status(conn);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@ -130,11 +180,12 @@ int mpd_put_state(char* buffer)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(buffer,
|
len = snprintf(buffer, MAX_SIZE,
|
||||||
"{\"type\":\"state\", \"data\":{"
|
"{\"type\":\"state\", \"data\":{"
|
||||||
" \"state\":%d, \"volume\":%d, \"repeat\":%d,"
|
" \"state\":%d, \"volume\":%d, \"repeat\":%d,"
|
||||||
" \"single\":%d, \"consume\":%d, \"random\":%d, "
|
" \"single\":%d, \"consume\":%d, \"random\":%d, "
|
||||||
" \"songpos\": %d, \"elapsedTime\": %d, \"totalTime\":%d"
|
" \"songpos\": %d, \"elapsedTime\": %d, \"totalTime\":%d, "
|
||||||
|
" \"currentsongid\": %d"
|
||||||
"}}",
|
"}}",
|
||||||
mpd_status_get_state(status),
|
mpd_status_get_state(status),
|
||||||
mpd_status_get_volume(status),
|
mpd_status_get_volume(status),
|
||||||
@ -144,10 +195,13 @@ int mpd_put_state(char* buffer)
|
|||||||
mpd_status_get_random(status),
|
mpd_status_get_random(status),
|
||||||
mpd_status_get_song_pos(status),
|
mpd_status_get_song_pos(status),
|
||||||
mpd_status_get_elapsed_time(status),
|
mpd_status_get_elapsed_time(status),
|
||||||
mpd_status_get_total_time(status));
|
mpd_status_get_total_time(status),
|
||||||
|
mpd_status_get_song_id(status));
|
||||||
|
|
||||||
|
printf("buffer: %s\n", buffer);
|
||||||
mpd_status_free(status);
|
mpd_status_free(status);
|
||||||
mpd_response_finish(conn);
|
//printf("status: %d\n", mpd_response_finish(conn));
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpd_put_current_song(char* buffer)
|
int mpd_put_current_song(char* buffer)
|
||||||
@ -167,27 +221,37 @@ int mpd_put_current_song(char* buffer)
|
|||||||
mpd_response_finish(conn);
|
mpd_response_finish(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpd_put_playlist(char** buffer)
|
int mpd_put_playlist(char* buffer)
|
||||||
{
|
{
|
||||||
mpd_send_list_queue_range_meta(conn, 0, 10);
|
char *cur = buffer;
|
||||||
int max_size = 1024*200;
|
const char *end = buffer + MAX_SIZE;
|
||||||
*buffer = (char **)malloc(max_size + LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING);
|
|
||||||
printf("Buffer init: %p %ud\n", *buffer, *buffer);
|
|
||||||
|
|
||||||
char *p = &((*buffer)[LWS_SEND_BUFFER_PRE_PADDING]);
|
|
||||||
|
|
||||||
struct mpd_entity *entity;
|
struct mpd_entity *entity;
|
||||||
|
struct mpd_song const *song;
|
||||||
|
|
||||||
|
mpd_send_list_queue_meta(conn);
|
||||||
|
|
||||||
|
cur += snprintf(cur, end - cur, "{\"type\": \"playlist\", \"data\": [ ");
|
||||||
|
|
||||||
for(entity = mpd_recv_entity(conn); entity; entity = mpd_recv_entity(conn)) {
|
for(entity = mpd_recv_entity(conn); entity; entity = mpd_recv_entity(conn)) {
|
||||||
|
|
||||||
if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
|
if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
|
||||||
struct mpd_song* song = mpd_entity_get_song(entity);
|
song = mpd_entity_get_song(entity);
|
||||||
p += snprintf(p, max_size, "ID: %d, Song: %s\n", mpd_song_get_id(song), mpd_song_get_uri(song));
|
cur += snprintf(cur, end - cur,
|
||||||
|
"{\"id\":%d, \"uri\":\"%s\", \"duration\":%d, \"title\":\"%s\"},",
|
||||||
|
mpd_song_get_id(song),
|
||||||
|
mpd_song_get_uri(song),
|
||||||
|
mpd_song_get_duration(song),
|
||||||
|
encode_string(mpd_song_get_tag(song, MPD_TAG_TITLE, 0))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entity != NULL)
|
|
||||||
mpd_entity_free(entity);
|
mpd_entity_free(entity);
|
||||||
}
|
}
|
||||||
|
//printf("status: %d\n", mpd_response_finish(conn));
|
||||||
|
|
||||||
printf("strlen is %d\n", strlen(p));
|
/* remove last ',' */
|
||||||
return strlen(*buffer + LWS_SEND_BUFFER_PRE_PADDING) +1;
|
cur--;
|
||||||
|
cur += snprintf(cur, end - cur, "] }");
|
||||||
|
printf("buffer: %s\n", buffer);
|
||||||
|
return cur - buffer;
|
||||||
}
|
}
|
@ -4,6 +4,8 @@
|
|||||||
#define DO_SEND_PLAYLIST (1 << 1)
|
#define DO_SEND_PLAYLIST (1 << 1)
|
||||||
#define DO_SEND_TRACK_INFO (1 << 2)
|
#define DO_SEND_TRACK_INFO (1 << 2)
|
||||||
|
|
||||||
|
struct libwebsocket_protocols *protocol_array;
|
||||||
|
|
||||||
struct per_session_data__ympd {
|
struct per_session_data__ympd {
|
||||||
int do_send;
|
int do_send;
|
||||||
};
|
};
|
||||||
@ -25,6 +27,9 @@ enum mpd_conn_states {
|
|||||||
#define MPD_API_SET_PLAY "MPD_API_SET_PLAY"
|
#define MPD_API_SET_PLAY "MPD_API_SET_PLAY"
|
||||||
#define MPD_API_SET_STOP "MPD_API_SET_STOP"
|
#define MPD_API_SET_STOP "MPD_API_SET_STOP"
|
||||||
#define MPD_API_SET_SEEK "MPD_API_SET_SEEK"
|
#define MPD_API_SET_SEEK "MPD_API_SET_SEEK"
|
||||||
|
#define MPD_API_SET_NEXT "MPD_API_SET_PREV"
|
||||||
|
#define MPD_API_SET_PREV "MPD_API_SET_NEXT"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int callback_ympd(struct libwebsocket_context *context,
|
int callback_ympd(struct libwebsocket_context *context,
|
||||||
@ -35,4 +40,4 @@ int callback_ympd(struct libwebsocket_context *context,
|
|||||||
void mpd_connect();
|
void mpd_connect();
|
||||||
int mpd_put_state(char* buffer);
|
int mpd_put_state(char* buffer);
|
||||||
int mpd_put_current_song(char* buffer);
|
int mpd_put_current_song(char* buffer);
|
||||||
int mpd_put_playlist(char** buffer);
|
int mpd_put_playlist(char* buffer);
|
||||||
|
Loading…
Reference in New Issue
Block a user