divan/DiwanRazor/Pages/Recitations/AudioClip.cshtml
Anas Rashid e8f2306422 Rename Ganjoor -> Diwan throughout the code
Projects (GanjooRazor -> DiwanRazor, GanjoorService.sln -> DiwanService.sln), files,
folders, classes, namespaces, settings, API routes (/api/diwan) and DB tables (Diwan*).
External addresses (ganjoor.net, github.com/ganjoor) unchanged. Migrations renamed
consistently (no pending model changes); requires a fresh database.
Upstream RUNNING_LOCALLY/SEMANTIC_SEARCH docs archived unmodified under docs/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:49:01 +02:00

310 lines
17 KiB
Plaintext

@page
@model DiwanRazor.Pages.AudioClipModel
@using DNTPersianUtils.Core
@{
Layout = null;
}
<!DOCTYPE html>
<html lang="ur-PK" dir="rtl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
<title>
دیوان » نمایش خوانش
</title>
<link href="~/dist/skin/pink.flag/css/jplayer.pink.flag.min.css" rel="stylesheet" type="text/css" />
<link href="~/css/p8.css" asp-append-version="true" rel="stylesheet" type="text/css" />
<partial name="_DiwanHead" />
<link rel="shortcut icon" href="/favicon.ico?version=1" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" title="دیوان" href="/search.xml" />
<script>
function wpopen(macagna) {
window.open(macagna, '_blank', 'width=600,height=700,scrollbars=yes,status=yes');
}
</script>
</head>
<body>
@if (!string.IsNullOrEmpty(Model.LastError))
{
<p>@Model.LastError</p>
}
else
{
<div style="width:95%;max-width:500px;min-width:380px;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 id="textcnt" style="display:table;width:100%;height:400px;vertical-align: bottom;background-image: url('https://source.unsplash.com/500x400/?flowers');color:white">
<div id="title1" style="display: table-row">
<p style="width:100%;height:25%;text-align:center;vertical-align: middle;font-family: 'Vazirmatn';display: table-cell;font-size: 1.5em;text-shadow: 2px 2px 4px white;">
@Model.Poem.Category.Poet.Nickname
</p>
</div>
<div id="title2" style="display: table-row">
<p style="width:100%;height:25%;text-align:center;vertical-align: middle;font-family: 'Vazirmatn';display: table-cell;font-size: 1.5em;text-shadow: 2px 2px 4px white;">
@for (int i = 1; i < Model.Poem.Category.Cat.Ancestors.Count; i++)
{
<text>
@Model.Poem.Category.Cat.Ancestors.ElementAt(i).Title &raquo;
</text>
}
@Model.Poem.Category.Cat.Title
</p>
</div>
<div id="title3" style="display: table-row">
<p style="width:100%;height:25%;text-align:center;vertical-align: middle;font-family: 'Vazirmatn';display: table-cell;font-size: 1.5em;text-shadow: 2px 2px 4px white;">
@Model.Recitation.AudioTitle
</p>
</div>
<div id="title4" style="display: table-row">
<p style="width:100%;height:25%;text-align:center;vertical-align: middle;font-family: 'Vazirmatn';display: table-cell;font-size: 1em;text-shadow: 2px 2px 4px white;">
به خوانش @Model.Recitation.AudioArtist
</p>
</div>
<div id="verse1div" style="display: table-row;visibility: hidden;">
<div style="width:100%;height:50%;text-align:center;vertical-align: bottom;font-family: 'Vazirmatn';display: table-cell;font-size: 1.5em;text-shadow: 2px 2px 4px white;">
<p id="verse1" style="width:80%;margin:auto;background-color:rgba(0, 0, 0, .4);margin-bottom:5px">
</p>
</div>
</div>
<div id="verse2div" style="display: table-row;visibility: hidden">
<div style="width:100%;height:50%;text-align:center;vertical-align: top;font-family: 'Vazirmatn';display: table-cell;font-size: 1.5em;text-shadow: 2px 2px 4px white;">
<p id="verse2" style="width:80%;margin:auto;background-color:rgba(0, 0, 0, .4);margin-top:5px">
</p>
</div>
</div>
<div id="normaldiv" style="display: table-row;visibility: hidden">
<div style="width:100%;height:100%;text-align:center;vertical-align: middle;font-family: 'Vazirmatn';display: table-cell;font-size: 1.5em;text-shadow: 2px 2px 4px white;">
<p id="normal" style="width:80%;margin:auto;background-color:rgba(0, 0, 0, .4);">
</p>
</div>
</div>
</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">
<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>
</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 class="jp-toggles">
<button class="jp-repeat" tabindex="0">تکرار</button>
</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>
<p style="font-family: 'Vazirmatn';font-size: 0.8em;color:darkgray">
تصویر پس‌زمینهٔ خوانش یک تصویر تصادفی از سایت <a href="https://unsplash.com/" target="_blank">unsplash.com</a> است و ارتباطی با محتوای شعر ندارد.
</p>
<p style="font-family: 'Vazirmatn';font-size: 1em">
فایل صوتی متناظر را می‌توانید در قالب mp3 از <a href="@Model.Recitation.Mp3Url" download>این نشانی</a> (اندازه @Html.Raw($"{(Model.Recitation.Mp3SizeInBytes / (1024.0 * 1024.0)):0.00}".ToPersianNumbers()) مگابایت) دریافت کنید.
</p>
<p style="font-family: 'Vazirmatn';font-size: 1em">
جهت دریافت خوانش با استفاده از دیوان رومیزی این مطلب را مطالعه بفرمایید. امکان ساخت کلیپهای ویدیویی از خوانشها با استفاده از خوانشگر دیوان رومیزی وجود دارد. جهت مشارکت در خوانش اشعار این صفحه و ویدیوهای آموزشی آن را ببینید.
</p>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/bk.js" asp-append-version="true"></script>
<script src="~/js/jplayersupport.js"></script>
<script src="~/js/vaabd.js?version=10"></script>
<script src="~/dist/jplayer/jquery.jplayer.min.js"></script>
<script src="~/dist/add-on/jplayer.playlist.min.js"></script>
<script>
@* Verse text is untrusted (user-submitted content, sanitized for storage but not for
safe embedding inside a <script> block) - it must never be spliced into a JS string
literal via @Html.Raw as it was here before, since a verse containing a stray "'" or
"</script>" would break out of the string. JsonSerializer.Serialize both quotes the
value correctly and HTML/JS-escapes '<', '>' and '&' by default, so the whole array
can be assigned directly and stays inert as data. *@
var verses = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Poem.Verses.Select(v => v.Text)));
@Html.Raw($" var normaltext = { (Model.Poem.Verses.Where(v => v.VersePosition == RMuseum.Models.Diwan.VersePosition.Paragraph).Any() ? "true" : "false") }")
function prepareclip(xmlfilename, poemtitle, auartist, oggurl, mp3url, verseArray) {
var verseStart = [];
var verseEnd = [];
var verseIndex = [];
var nLastHighlight = -1;
var vCount = 0;
audioxmlfiles[0] = xmlfilename;
var jlist = new jPlayerPlaylist({
jPlayer: "#jquery_jplayer_1",
cssSelectorAncestor: "#jp_container_1"
}, [
{
title: poemtitle,
artist: auartist,
mp3: mp3url
},
],
{
setmedia: function(event) {
$.ajax({
type: "GET",
url: audioxmlfiles[jlist.current],
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;
}
});
},
timeupdate: function(event) { // 4Hz
var curTime = event.jPlayer.status.currentTime;
if (curTime > 0) {
if (normaltext == true) {
for (i = 0; i <= vCount; i++) {
if (curTime >= verseStart[i] && curTime <= verseEnd[i]) {
if (nLastHighlight != verseIndex[i]) {
$('#title1').hide();
$('#title2').hide();
$('#title3').hide();
$('#title4').hide();
$('#normal').text(verseArray[verseIndex[i]]);
$('#verse1div').css("visibility", "hidden");
$('#verse2div').css("visibility", "hidden");
$('#verse1div').hide();
$('#verse2div').hide();
$('#normaldiv').css("visibility", "visible");
}
nLastHighlight = verseIndex[i];
break;
}
}
}
else {
for (i = 0; i <= vCount; i += 2) {
if (curTime >= verseStart[i] && curTime <= verseEnd[i]) {
if (nLastHighlight != verseIndex[i]) {
$('#title1').hide();
$('#title2').hide();
$('#title3').hide();
$('#title4').hide();
$('#verse1').text(verseArray[verseIndex[i]]);
$('#verse2').text(verseArray[verseIndex[i] + 1]);
$('#normaldiv').css("visibility", "hidden");
$('#normaldiv').hide();
$('#verse1div').css("visibility", "visible");
$('#verse2div').css("visibility", "visible");
}
nLastHighlight = verseIndex[i];
break;
}
}
}
}
},
ended: function(event) { // 4Hz
},
swfPath: "dist/jplayer",
supplied: "mp3",
wmode: "window",
useStateClassSkin: true,
autoBlur: false,
smoothPlayBar: true,
keyEnabled: true,
remainingDuration: true,
toggleDuration: true
});
return jlist;
}
//<![CDATA[
$(document).ready(function() {
prepareclip('@Html.Raw($"{DiwanRazor.APIRoot.InternetUrl}/api/audio/file/{Model.Recitation.Id}.xml")', '@Model.Recitation.AudioTitle',
'به خوانش @Model.Recitation.AudioArtist', '', '@Model.Recitation.Mp3Url', verses);
});
//]]>
</script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{
@Html.Raw(ViewData["TrackingScript"])
}
}
</body>
</html>