Merge pull request #253 from ganjoor/change-audio-player

Change audio player
This commit is contained in:
Hamid Reza Mohammadi 2021-12-01 22:18:04 +03:30 committed by GitHub
commit 160bae422f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 260 additions and 152 deletions

View File

@ -55,6 +55,75 @@
<body>
<script src="/js/vaabd.js"></script>
@if (Model.IsPoemPage)
{
if (Model.GanjoorPage != null && Model.GanjoorPage.Poem.Recitations.Length > 0)
{
<script>
var currentAudio = null;
var verseStart = [];
var verseEnd = [];
var verseIndex = [];
var nLastHighlight = -1;
var vCount = 0;
var _setXml = function (xmlUrl) {
$.ajax({
type: "GET",
url: xmlUrl,
dataType: "xml",
success: function (xml) {
var nOneSecondBugFix = 2000;
$(xml).find('OneSecondBugFix').each(function () {
nOneSecondBugFix = parseInt($(xml).find('OneSecondBugFix').text());
});
var v = 0;
$(xml).find('SyncInfo').each(function () {
verseStart[v] = parseInt($(this).find('AudioMiliseconds').text()) / nOneSecondBugFix;
verseIndex[v] = parseInt($(this).find('VerseOrder').text());
if (v > 0)
verseEnd[v - 1] = verseStart[v];
v++;
});
v--;
if (v > 1)
verseEnd[v] = verseStart[v] + 2 * (verseEnd[v - 1] - verseStart[v - 1]);
vCount = v;
}
});
}
var _trackTimeChanged = function (audio) {
var currentTime = audio.currentTime;
if (currentTime > 0) {
for (var i = 0; i <= vCount; i++) {
if (currentTime >= verseStart[i] && currentTime <= verseEnd[i]) {
hilightverse(verseIndex[i], "red", true, playerScrollLock);
if (nLastHighlight != verseIndex[i] && nLastHighlight != -1)
hilightverse(nLastHighlight, "black", false, false);
nLastHighlight = verseIndex[i];
break;
}
}
}
};
</script>
<script>
var narrators = [];
@foreach (var recitation in Model.GanjoorPage.Poem.Recitations)
{
<text>
narrators.push('@Html.Raw(recitation.AudioArtist)');
audioxmlfiles.push('@($"{GanjooRazor.APIRoot.InternetUrl}/api/audio/file/{recitation.Id}.xml")');
</text>
}
</script>
}
}
@if (Model.IsHomePage)
{
@if (!string.IsNullOrEmpty(Model.LastError))
@ -78,60 +147,6 @@
@{
if (Model.IsPoemPage)
{
if (Model.GanjoorPage != null && Model.GanjoorPage.Poem.Recitations.Length > 0)
{
<script src="/dist/jplayer/jquery.jplayer.min.js"></script>
<script src="/dist/add-on/jplayer.playlist.min.js"></script>
<script>
//<![CDATA[
$(document).ready(function () {
var jlist = prepaudio(
"@Html.Raw($"{GanjooRazor.APIRoot.InternetUrl}/api/audio/file/{Model.GanjoorPage.Poem.Recitations[0].Id}.xml")",
"@Html.Raw(Model.GanjoorPage.Poem.Recitations[0].AudioTitle)",
"@Html.Raw(Model.getAudioDesc(Model.GanjoorPage.Poem.Recitations[0], true))",
"",
"@Html.Raw(Model.GanjoorPage.Poem.Recitations[0].Mp3Url)"
);
@for (int x = 1; x < Model.GanjoorPage.Poem.Recitations.Length; x++)
{
<text>
addpaudio(@x, jlist,
"@Html.Raw($"{GanjooRazor.APIRoot.InternetUrl}/api/audio/file/{Model.GanjoorPage.Poem.Recitations[x].Id}.xml")",
"@Html.Raw(Model.GanjoorPage.Poem.Recitations[x].AudioTitle)",
"@Html.Raw(Model.getAudioDesc(Model.GanjoorPage.Poem.Recitations[x], false))",
"",
"@Html.Raw(Model.GanjoorPage.Poem.Recitations[x].Mp3Url)"
);
</text>
}
if (playerScrollLock) {
$('#scroll-lock').text('🔒');
}
else {
$('#scroll-lock').text('🔓');
}
$('#scroll-lock').click(function () {
playerScrollLock = !playerScrollLock;
if (playerScrollLock) {
$('#scroll-lock').text('🔒');
}
else {
$('#scroll-lock').text('🔓');
}
});
});
//]]>
</script>
}
}
if (!string.IsNullOrEmpty(Model.PinterestUrl))
{
<script>

View File

@ -195,6 +195,14 @@ namespace GanjooRazor.Pages
};
}
public _AudioPlayerPartialModel GetRecitationsModel(PublicRecitationViewModel[] recitations)
{
return new _AudioPlayerPartialModel()
{
Recitations = recitations
};
}
public async Task<ActionResult> OnPostReply(string replyCommentText, int refPoemId, int refCommentId)
{
return await OnPostComment(replyCommentText, refPoemId, refCommentId, -1);

View File

@ -0,0 +1,45 @@
@model GanjooRazor.Pages._AudioPlayerPartialModel
@using DNTPersianUtils.Core
@{
}
<div class="container">
@for (var nRecitationIndex = 0; nRecitationIndex < Model.Recitations.Length; nRecitationIndex++)
{
var recitaion = Model.Recitations[nRecitationIndex];
<div class="@Model.CSSClass(nRecitationIndex)">
<audio id="audio-@(nRecitationIndex + 1)" preload="none" controls>
<source src="@recitaion.Mp3Url" title="@($"{recitaion.AudioTitle} به خوانش {recitaion.AudioArtist}")" data-track-number="@(nRecitationIndex + 1)" />
مرورگر شما از پخش صدای HTML 5 پشتیبانی نمی‌کند.
</audio>
<div class="recitaion-info">
<a role="button" onclick="document.getElementById('audio-@(nRecitationIndex + 1)').play()" class="actionlink">@recitaion.AudioTitle</a> @Html.Raw(Model.getAudioDesc(recitaion, nRecitationIndex == 0))
</div>
<script>
document.getElementById('audio-@(nRecitationIndex + 1)').addEventListener('play', () => {
currentAudio = document.getElementById('audio-@(nRecitationIndex + 1)');
var audioList = document.querySelectorAll('audio');
audioList.forEach(function(audioElement) {
if(audioElement != currentAudio){
audioElement.pause();
}
});
_setXml('@($"{GanjooRazor.APIRoot.InternetUrl}/api/audio/file/{recitaion.Id}.xml")');
});
document.getElementById('audio-@(nRecitationIndex + 1)').addEventListener('timeupdate', () => {
_trackTimeChanged(document.getElementById('audio-@(nRecitationIndex + 1)'));
});
</script>
</div>
@if (nRecitationIndex == 4 && Model.Recitations.Length > 5)
{
<a role="button" class="pagebutton" id="load-all-recitations" onclick="showAllRecitations()">همهٔ خوانش‌ها<i class="info-buttons">autorenew</i></a>
}
}
</div>

View File

@ -0,0 +1,49 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
using RMuseum.Models.GanjoorAudio.ViewModels;
namespace GanjooRazor.Pages
{
public class _AudioPlayerPartialModel : PageModel
{
public PublicRecitationViewModel[] Recitations { get; set; }
public string getAudioDesc(PublicRecitationViewModel recitation, bool contributionLink = false)
{
string audiodesc = "به خوانش ";
if (!string.IsNullOrEmpty(recitation.AudioArtistUrl))
{
audiodesc += $"<a href='{recitation.AudioArtistUrl}'>{recitation.AudioArtist}</a>";
}
else
{
audiodesc += $"{recitation.AudioArtist}";
}
if (!string.IsNullOrEmpty(recitation.AudioSrc))
{
if (!string.IsNullOrEmpty(recitation.AudioSrcUrl))
{
audiodesc += $" <a href='{recitation.AudioSrcUrl}'>{recitation.AudioSrc}</a>";
}
else
{
audiodesc += $" {recitation.AudioSrc}";
}
}
audiodesc += $" <small><a href='/AudioClip/?a={recitation.Id}' onclick='wpopen(this.href); return false' class='comments-link' title='دریافت'>(دریافت)</a></small>";
if (contributionLink)
{
audiodesc += "<br /> <small>می‌خواهید شما بخوانید؟ <a href='http://ava.ganjoor.net/about/'>اینجا</a> را ببینید.</small>";
}
return audiodesc;
}
public string CSSClass(int recitationIndex)
{
return recitationIndex < 5 ? "audio-player" : "hidden-recitation";
}
}
}

View File

@ -136,7 +136,9 @@
</div>
<div style="width:164px;margin:auto" id="page-hierarchy">
@{
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Poet.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Poet.Name)</a><span> &raquo;</span>
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Poet.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Poet.Name)</a>
<span> &raquo;</span>
<h2><a href="@Html.Raw(Model.GanjoorPage.FullUrl)">@Html.Raw(Model.GanjoorPage.Title)</a></h2>
}
</div>
@ -151,7 +153,9 @@
@{
foreach (var gran in Model.GanjoorPage.PoetOrCat.Cat.Ancestors)
{
<a href="@Html.Raw(gran.FullUrl)">@Html.Raw(gran.Title)</a><span> &raquo;</span>
<a href="@Html.Raw(gran.FullUrl)">@Html.Raw(gran.Title)</a>
<span> &raquo;</span>
}
@if (!Model.IsPoemPage && !Model.IsCatPage && !Model.IsPoetPage)
@ -168,7 +172,9 @@
{
@if (Model.IsPoemPage)
{
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Title)</a><span> &raquo;</span>
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Title)</a>
<span> &raquo;</span>
<h2>
<a href="@Html.Raw(Model.GanjoorPage.Poem.FullUrl)" rel="bookmark">
@Html.Raw(Model.GanjoorPage.Poem.Title)
@ -191,65 +197,7 @@
@Html.Raw(Model.GanjoorPage.HtmlText)
}
</article>
@{
if (Model.IsPoemPage)
{
if (Model.GanjoorPage.Poem.Recitations.Length > 0)
{
<div class="spacer">&nbsp;</div>
<div style="width:95%;max-width:500px;margin:auto">
<div id="jp_container_1" class="jp-video jp-video-270p">
<div class="jp-type-playlist">
<div id="jquery_jplayer_1" class="jp-jplayer"></div>
<div class="jp-gui">
<div class="jp-video-play">
<button class="jp-video-play-icon" tabindex="0">پخش</button>
</div>
<div class="jp-interface">
<div class="jp-progress">
<div class="jp-seek-bar">
<div class="jp-play-bar"></div>
</div>
</div>
<div class="jp-current-time">&nbsp;</div>
<div class="jp-duration">&nbsp;</div>
<div class="jp-controls-holder" style="width:auto">
<div class="jp-controls">
<button class="jp-previous" tabindex="0">قبلی</button>
<button class="jp-play" tabindex="0">پخش</button>
<button class="jp-next" tabindex="0">بعدی</button>
<button class="jp-stop" tabindex="0">توقف</button>
<a id="scroll-lock" role="button" title="اسکرول خودکار در هنگام پخش خوانش" style="cursor: pointer; position:absolute; right: 20px; top: 10px;" tabindex="0">🔒</a>
</div>
<div class="jp-volume-controls">
<button class="jp-mute" tabindex="0">بی‌صدا</button>
<button class="jp-volume-max" tabindex="0">حداکثر صدا</button>
<div class="jp-volume-bar">
<div class="jp-volume-bar-value"></div>
</div>
</div>
</div>
<div class="jp-details">
<div class="jp-title">&nbsp;</div>
</div>
</div>
</div>
<div class="jp-playlist">
<ul>
<!-- The method Playlist.displayPlaylist() uses this unordered list -->
<li>&nbsp;</li>
</ul>
</div>
<div class="jp-no-solution">
<span>نیاز به بروزآوری</span>
جهت خوانش شعر شما یا باید از مرورگر جدیدی همچون <a href="http://getfirefox.com/">فایرفاکس</a> استفاده کنید یا افزونه <a href="http://get.adobe.com/flashplayer/" target="_blank">فلش</a> مرورگرتان را بروزآوری کنید.
</div>
</div>
</div>
</div>
}
}
}
@{
if (Model.IsCatPage)
{
@ -259,13 +207,17 @@
<div class="navleft">
@if (Model.GanjoorPage.PoetOrCat.Cat.Next != null)
{
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Next.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Next.Title)</a><span> &raquo;</span>
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Next.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Next.Title)</a>
<span> &raquo;</span>
}
</div>
<div class="navright">
@if (Model.GanjoorPage.PoetOrCat.Cat.Previous != null)
{
<span>&laquo; </span><a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Previous.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Previous.Title)</a>
<span>&laquo; </span>
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Previous.FullUrl)">@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Previous.Title)</a>
}
</div>
</div>
@ -281,23 +233,31 @@
<div class="navleft">
@if (Model.GanjoorPage.Poem.Next != null)
{
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.FullUrl + "/" + Model.GanjoorPage.Poem.Next.UrlSlug)">@Html.Raw(Model.GanjoorPage.Poem.Next.Title): @Html.Raw(Model.GanjoorPage.Poem.Next.Excerpt)</a><span> &raquo;</span>
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.FullUrl + "/" + Model.GanjoorPage.Poem.Next.UrlSlug)">@Html.Raw(Model.GanjoorPage.Poem.Next.Title): @Html.Raw(Model.GanjoorPage.Poem.Next.Excerpt)</a>
<span> &raquo;</span>
}
else
if (Model.GanjoorPage.Poem.Category.Cat.Next != null)
if (Model.GanjoorPage.Poem.Category.Cat.Next != null)
{
<a href="@Model.GanjoorPage.Poem.Category.Cat.Next.FullUrl">@Model.GanjoorPage.Poem.Category.Cat.Next.Title</a><span> &raquo;</span>
<a href="@Model.GanjoorPage.Poem.Category.Cat.Next.FullUrl">@Model.GanjoorPage.Poem.Category.Cat.Next.Title</a>
<span> &raquo;</span>
}
</div>
<div class="navright">
@if (Model.GanjoorPage.Poem.Previous != null)
{
<span>&laquo; </span><a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.FullUrl + "/" +Model.GanjoorPage.Poem.Previous.UrlSlug)">@Html.Raw(Model.GanjoorPage.Poem.Previous.Title) :@Html.Raw(Model.GanjoorPage.Poem.Previous.Excerpt)</a>
<span>&laquo; </span>
<a href="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.FullUrl + "/" +Model.GanjoorPage.Poem.Previous.UrlSlug)">@Html.Raw(Model.GanjoorPage.Poem.Previous.Title) :@Html.Raw(Model.GanjoorPage.Poem.Previous.Excerpt)</a>
}
else
if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
{
<span>&laquo; </span><a href="@Model.GanjoorPage.Poem.Category.Cat.Previous.FullUrl">@Model.GanjoorPage.Poem.Category.Cat.Previous.Title</a>
<span>&laquo; </span>
<a href="@Model.GanjoorPage.Poem.Category.Cat.Previous.FullUrl">@Model.GanjoorPage.Poem.Category.Cat.Previous.Title</a>
}
</div>
</div>
@ -306,7 +266,6 @@ if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
<div id="comments">
<div class="poem-info">
<p>
<small><i class="pageicons">mouse</i> با دو بار کلیک روی واژه‌ها یا انتخاب متن و کلیک روی آنها می‌توانید آنها را در لغتنامهٔ دهخدا جستجو کنید.</small>
@ -403,6 +362,21 @@ if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
<a role="button" class="textualbutton" href="/login">برای ویرایش و بهبود متن با نام کاربری خود وارد شوید</a>
}
@{
if (Model.IsPoemPage)
{
if (Model.GanjoorPage.Poem.Recitations.Length > 0)
{
<div class="related-images-frame">
<div class="century">
@(Model.GanjoorPage.Poem.Recitations.Length > 1 ? "خوانش‌ها" : "خوانش")
</div>
<partial name="_AudioPlayerPartial" model=Model.GetRecitationsModel(Model.GanjoorPage.Poem.Recitations) />
</div>
}
}
}
@if (Model.GanjoorPage.Poem.Top6RelatedPoems.Length > 0)
{
<div class="related-images-frame">
@ -595,7 +569,7 @@ if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
<div id="id02" class="modal">
<span onclick="document.getElementById('id02').style.display='none'"
class="close" title="بستن">&times;</span>
class="close" title="بستن">&times;</span>
<form class="modal-content animate" method="post" id="editcommentform" action="?handler=EditComment">
<table style="max-width:100%; width:100%; margin:0">
<tr>
@ -617,7 +591,7 @@ if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
<div id="id03" class="modal">
<span onclick="document.getElementById('id03').style.display='none'"
class="close" title="بستن">&times;</span>
class="close" title="بستن">&times;</span>
<form class="modal-content animate" method="post" id="replycommentform" action="?handler=Reply">
<table style="max-width:100%; width:100%; margin:0">
<tr>
@ -665,13 +639,17 @@ if (Model.GanjoorPage.Poem.Category.Cat.Previous != null)
<div class="navleft">
@if (Model.GanjoorPage.Next != null)
{
<a href="@Html.Raw(Model.GanjoorPage.Next.FullUrl)">@Html.Raw(Model.GanjoorPage.Next.Title)</a><span> &raquo;</span>
<a href="@Html.Raw(Model.GanjoorPage.Next.FullUrl)">@Html.Raw(Model.GanjoorPage.Next.Title)</a>
<span> &raquo;</span>
}
</div>
<div class="navright">
@if (Model.GanjoorPage.Previous != null)
{
<span>&laquo; </span><a href="@Html.Raw(Model.GanjoorPage.Previous.FullUrl)">@Html.Raw(Model.GanjoorPage.Previous.Title)</a>
<span>&laquo; </span>
<a href="@Html.Raw(Model.GanjoorPage.Previous.FullUrl)">@Html.Raw(Model.GanjoorPage.Previous.Title)</a>
}
</div>
</div>

View File

@ -348,7 +348,7 @@ div.n, div.l {
padding-top: 20px;
}
.ganjoor-comment, .inlinesimi {
.ganjoor-comment, .inlinesimi, .audio-player {
margin-right: 20px;
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
transition: 0.3s;
@ -358,7 +358,7 @@ div.n, div.l {
overflow-x: hidden;
}
.inlinesimi {
.inlinesimi, .audio-player {
margin-left: 20px;
}
@ -1123,3 +1123,11 @@ ol {
#footer .link-list-tools li {
padding-right: 50px;
}
.recitaion-info{
}
.hidden-recitation {
display: none;
}

View File

@ -125,10 +125,6 @@ function btshmr(poemId) {
setTimeout(function () { btshmr_internal(poemId); }, 1);
}
function hilightverse(vnum, clr, sc, forceScroll) {
var root = document;
if (typeof root == "string") root = document.getElementById(root);
@ -152,12 +148,12 @@ function hilightverse(vnum, clr, sc, forceScroll) {
btn.setAttribute('role', 'button');
btn.className = 'inlineanchor';
btn.onclick = function () {
if ($('#jquery_jplayer_1').data().jPlayer.status.paused) {
$('#jquery_jplayer_1').data().jPlayer.play();
if (currentAudio.paused) {
currentAudio.play();
$('#InlinePauseButtonImage').text('pause_circle_filled');
}
else {
$('#jquery_jplayer_1').data().jPlayer.pause();
currentAudio.pause();
$('#InlinePauseButtonImage').text('play_circle_filled');
}
};
@ -221,12 +217,12 @@ function hilightverse(vnum, clr, sc, forceScroll) {
btn.setAttribute('role', 'button');
btn.className = 'inlineanchor';
btn.onclick = function () {
if ($('#jquery_jplayer_1').data().jPlayer.status.paused) {
$('#jquery_jplayer_1').data().jPlayer.play();
if (currentAudio.paused) {
currentAudio.play();
$('#InlinePauseButtonImage').text('pause_circle_filled');
}
else {
$('#jquery_jplayer_1').data().jPlayer.pause();
currentAudio.pause();
$('#InlinePauseButtonImage').text('play_circle_filled');
}
};
@ -419,12 +415,11 @@ function getVerseIndexFromCoupleIndex(coupletIndex) {
function playCouplet(coupletIndex) {
var vIndex = getVerseIndexFromCoupleIndex(coupletIndex);
if (jlist.isPlaying) {
jlist.pause();
}
var comboId = '#narrators-' + coupletIndex;
var recitationIndex = $(comboId).find(":selected").val()
jlist.select(recitationIndex);
var recitationIndex = parseInt($(comboId).find(":selected").val());
var recitationOrder = recitationIndex + 1;
if (audioxmlfiles.length > 0) {
$.ajax({
@ -443,13 +438,15 @@ function playCouplet(coupletIndex) {
var v = parseInt($(this).find('VerseOrder').text())
if (v == vIndex) {
var verseStart = parseInt($(this).find('AudioMiliseconds').text()) / nOneSecondBugFix;
$(jlist.cssSelector.jPlayer).jPlayer("play");
var audioControl = document.getElementById('audio-' + String(recitationOrder));
audioControl.play();
var buttonList = '#listen-' + coupletIndex;
$(buttonList).text('در حال دریافت خوانش ...');
setTimeout(function () {
$(jlist.cssSelector.jPlayer).jPlayer("play", verseStart);
audioControl.currentTime = verseStart;
$(buttonList).text('در حال خواندن');
}, 100);
foundCouplet = true;
var buttonList = '#listen-' + coupletIndex;
$(buttonList).text('در حال خواندن');
return false;
}
});
@ -899,4 +896,12 @@ function loadMoreRelatedFromPoet(poetId, rhythm, rhymeLetters, skipPoemFullUrl1,
$(data).appendTo(document.getElementById(divId));
},
});
}
function showAllRecitations() {
const hiddenRecitations = document.querySelectorAll('.hidden-recitation');
hiddenRecitations.forEach(function (recitation) {
recitation.className = 'audio-player';
});
document.getElementById('load-all-recitations').style.display = 'none';
}

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
# Visual Studio Version 17
VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RSecurityBackend", "RSecurityBackend\RSecurityBackend.csproj", "{1BF45DCD-40F4-4D6E-9134-D6B3DE39C56E}"
EndProject