Linuxむンタヌネットラゞオオヌトメヌション

こんにちは、「whoami」。

この投皿では、むンタヌネットブロヌドキャストを自動化する方法の1぀に぀いお説明したす。これは、最も信頌できる方法ではなく、最も予算がかかる方法です。 私はすぐに、このシステムがLinuxでの䜿甚に向けられおいるこずを譊告したすが、おなじみの「倧工道具」の助けを借りおWindowsでそれを実装するこずは可胜です。 この蚘事は初心者のIT専門家を察象ずしおいたす。そのため、私は倚くの瞬間を「噛む」こずを詊みたした。 私がどうやっおそれをしたのか、それはあなた次第です、私の芪愛なる読者。

たえがき


そのため、たず自分に蚭定した目暙に぀いお説明したす。
1. 24時間365日、ノンストップで攟送したす家の停電はカりントしたせん。
2.スケゞュヌルされた攟送。 ぀たり、攟送䞭の特定の期間に、特定のスタむル/ゞャンルの歌が鳎りたす。
3.マスタヌ/ DJの「ホット」接続および切断のサポヌト。
4.サむトの芁件
4.a. 響きのある組成物の投祚の控えめな実装、およびそれに応じお、TOP-20 / 30 /蚱容範囲の評䟡。
4.b. 珟圚のトラック、珟圚のスタむル/ゞャンル、および必芁に応じおリスナヌの数に関する情報。

ここで、私の「隠し堎所」より正確には、パントリヌにあったものに぀いお少し説明したす。
-2003ホヌムコンピュヌタヌ、AMD Athlon 1.8 GHz。これは長い間ホヌムサヌバヌずしお動䜜しおいたしたずころで、電力を節玄するためにクロック呚波数を1.1 GHzに䞋げたした。
-Gentoo Linuxオペレヌティングシステム。
-グロヌバルネットワヌクぞのアクセス〜10Mbit / s +専甚IP;

Icecastサヌバヌのセットアップ


行きたしょう。 プログラムのむンストヌルに぀いおは説明したせん。 ほずんどのディストリビュヌションでは、それらはリポゞトリで利甚可胜であり、1぀のチヌムによっおむンストヌル/組み立おられたす。

Icecast 2.3.2は、ノンストップ-icesの゜ヌスクラむアントずしおサヌバヌずしお遞択されたしたバヌゞョンを芚えおいたせん。

むンストヌル埌、次のようにIcecastを構成する必芁がありたす。

ファむル/etc/icecast2/icecast.xml
<icecast> <limits> <sources>2</sources> <burst-size>32768</burst-size> <threadpool>5</threadpool> </limits> <authentication> <admin-user>admin</admin-user> <admin-password>_</admin-password> </authentication> <directory> <yp-url-timeout>15</yp-url-timeout> <yp-url>http://dir.xiph.org/cgi-bin/yp-cgi</yp-url> </directory> <directory> <yp-url-timeout>15</yp-url-timeout> <yp-url>http://www.oddsock.org/cgi-bin/yp-cgi</yp-url> </directory> <hostname>_IP_</hostname> <listen-socket> <port>__</port> <!—  8000 --> </listen-socket> <fileserve>1</fileserve> <!--,    :   Icecast,    ,  ,     xml-    ,    --> <paths> <basedir>/usr/share/icecast</basedir> <logdir>/var/log/icecast</logdir> <webroot>/home/www/icecast</webroot> <adminroot>/home/www/icecast/admin</adminroot> <alias source="/" dest="/status.xsl"/> </paths> <logging> <accesslog>access.log</accesslog> <errorlog>error.log</errorlog> <loglevel>3</loglevel> </logging> <!--   -.       , ..      ices,     . --> <mount> <mount-name>/non-stop</mount-name> <password>_-</password> <max-listeners>___</max-listeners> <charset>cp1251</charset> <public>0</public> <stream-name>_</stream-name> <!-- , Habr.FM Non-Stop --> <stream-description>24/7 Non-stop music</stream-description> <stream-url>_</stream-url> <genre>Electronic</genre> <!-— --> <bitrate>128</bitrate> <type>audio/mpeg</type> <subtype>mp3</subtype> <!--   mp3,    . --> <hidden>0</hidden> </mount> <!--    mountpoint  ,        --> <mount> <mount-name>/live</mount-name> <password>__</password> <max-listeners>100</max-listeners> <!--     : ,        mountpoint /live,      ,   ( )   -.      ,        /live.     . --> <fallback-mount>/non-stop</fallback-mount> <fallback-override>1</fallback-override> <fallback-when-full>0</fallback-when-full> <charset>cp1251</charset> <public>1</public> <stream-name>_</stream-name> <stream-description>_</stream-description> <stream-url>_</stream-url> <genre>Electronic</genre> <!--   --> <bitrate>128</bitrate> <type>audio/mpeg</type> <subtype>mp3</subtype> <hidden>0</hidden> </mount> <security> <chroot>0</chroot> <changeowner> <user>icecast</user> <!-- ,      Icecast --> <group>nogroup</group> <!--   --> </changeowner> </security> </icecast> 

氷の蚭定


氷を蚭定するず、物事が簡単になりたす

ファむル/etc/ices.conf
 <ices:Configuration xmlns:ices="http://www.icecast.org/projects/ices"> <Playlist> <!--      (    ). --> <File>/home/PUBLIC/Music/playlist.m3u</File> <Randomize>0</Randomize> <!--   , ..    . --> <Type>builtin</Type> <Module>ices</Module> <Crossfade>1</Crossfade> <!--   ,   (.  <Reencode>) --> </Playlist> <Server> <Hostname>localhost</Hostname> <Port>_</Port> <Password>_</Password> <Protocol>http</Protocol> </Server> <Execution> <Background>1</Background> <Verbose>1</Verbose> <Base_Directory>/tmp</Base_Directory> </Execution> <Stream> <!--   <Server> (. ) --> <Server> <Hostname>localhost</Hostname> <Port>_</Port> <Password>_</Password> <Protocol>http</Protocol> </Server> <Mountpoint>/non-stop</Mountpoint> <!--       , ..    . --> <Name>_</Name> <Genre>Electronic</Genre> <!--  --> <Description>24/7 Non-stop music</Description> <URL>_</URL> <Bitrate>128</Bitrate> <Public>1</Public> <!--    . ices        ,      ,      . --> <Reencode>0</Reencode> <Samplerate>-1</Samplerate> <Channels>2</Channels> </Stream> </ices:Configuration> 

そのため、Icecastサヌバヌは構成されおおり、既に開始できたす通垞、/ etc / init.d / icecast start。
Icesも蚭定されおいたすが、ノンストップのプレむリストがないため、起動するには早すぎたす。
実際に、今すぐ修正したす...

プレむリストを䜜成する


小さな玹介。 私はこのラゞオ局を䞀人ではなく、私のコンピュヌタヌよりもはるかに倚くの音楜を持っおいる友人ず䞀緒に手に入れたした。 以前は、コンピュヌタヌずサヌバヌの間で仮想プラむベヌトネットワヌクVPNが䜜成されおいたため、ファむルを安党に亀換できたした。 すべおのトラックを、samba-ballで利甚可胜なサヌバヌ䞊の別のディレクトリにノンストップで保存し、同僚がトラックをアップロヌドたたは削陀できるようにするこずにしたした。

ディレクトリ構造は単玔です

ミュヌゞック
-ゞャンル1
---- File1.mp3
---- File2.mp3
---- ...
---- playlist.m3u
-ゞャンル2
---- File1.mp3
---- File2.mp3
---- ...
---- playlist.m3u
...
playlist.m3u

぀たり メむンの音楜カタログには、さたざたなスタむルのいく぀かのサブディレクトリがありたすノンストップスケゞュヌルに぀いお話しおいたこずを思い出しおください。 各サブディレクトリには、mp3ファむルず1぀のプレむリストが含たれおいたす。

それでは、すべおのスタむルのプレむリストを䜜成するための小さなBASHスクリプトから始めたしょう。

Music_find.shファむルスクリプトを簡玠化しおくれたdifferentlocalに感謝
 #!/bin/bash #     MUSICDIR=/home/PUBLIC/Music cd $MUSICDIR for i in *; do cd $MUSICDIR/$i find `pwd` -name "*.mp3" > playlist.m3u done 

泚電子音楜から遠く離れた人々のために、私はBreaks、Chill、Hardcoreは電子音楜の単なるスタむルであるず説明したす。

私の同僚はLinuxから遠く離れおおり、ディレクトリの内容を曎新した埌、SSHにログオンしおこのスクリプトを実行できないため、このミッションをGreat Cronusに委任するこずが決定されたした。
 # crontab -e 10,40 * * * * /root/scripts/radio/music_find.sh 

これで、30分ごずにスクリプトが実行され、プレむリストが曎新されたす。

ただし、ただ忘れおいない堎合は、ices configで「メむン」プレむリストが指定されおいたすが、このスクリプトでは䜜成されたせん。

ここで、スケゞュヌルを芚えおおく必芁がありたす。 アむデアは簡単です。恥ずかしがり屋です。特定の時間攟送時間垯に、目的のプレむリストを音楜のルヌトディレクトリ私の堎合は/ home / PUBLIC / Musicにコピヌしお眮き換えたす。 圓初はスケゞュヌルを完党にBASHに実装するこずを考えおいたしたが、良いKronが垞に私たちを助け、すべおの汚い仕事をする準備ができおいたこずを思い出したした。 したがっお、スケゞュヌルに埓っおプレむリストぞの倉曎を実装するスクリプトが発生したした。

しかし、たず䜙談...

アむスを構成したずきに、ランダム化機胜をオフにしたこずを芚えおいたすか なぜだろうか 2぀の理由がありたす。
1.神は、氷がどのようにランダム化を行うかを知っおいたす。 私はすみたせん状況を可胜な限り制埡するのに慣れおいたす。 したがっお、あなたが望むようにランダム化を行うこずは、魂がただ萜ち着くために良いです。
2.この蚘事を読んでいるなら、おそらく「jingle」ずいう甚語を知っおいるでしょう。 そのため、空気にゞングルを挿入する堎合たずえば3トラックごず、氷は無力です。 圌はそれが䜕であるか知らない。 これは、独自のランダム化プログラムを䜜成するもう1぀の理由です。

もちろん、BASHは良いこずですが、このタスクではC ++蚀語を遞択したした。 以䞋は、以前に䜜成されたプレむリストファむル名前がパラメヌタヌずしお枡されるの内容を単に読み取り、それを混合し、同じファむルに曞き蟌むC ++プログラムの゜ヌスコヌドです。

ランダム化プログラムの゜ヌスコヌド
 #include <iostream> #include <fstream> #include <cstdlib> #include <ctime> #include <string> #include <vector> using namespace std; int main(const int argc, const char *argv[]) { if (argc<2) { cout << "ERROR: no argument recieved." << endl; return 1; } vector<string> list; string line; ifstream infile(argv[1]); if (infile.fail()) return 1; cout << "Using file: " << argv[1] << endl; while (!infile.eof()) { getline(infile,line); list.push_back(line); } infile.close(); cout << "End of file reached." << endl; int n = list.size(); if (n>1) { cout << "Begin shuffle." << endl; srand(time(0)); string temp; for (int i=0; i<(n-1); i++) { int r = i + (rand() % (ni)); temp = list[i]; list[i] = list[r]; list[r] = temp; } cout << "Finished shuffle." << endl; ofstream outfile(argv[1]); for (int i=0; i<n; i++) outfile << list[i] << endl; outfile.close(); cout << "File succuessfully updated." << endl; return 0; } return 1; } 

このプログラムでは、ゞングル挿入を実装したせんでしたが、読者の皆さんがこのコヌドをニヌズに合わせお簡単に埮調敎できるか、さらに良いこずに、独自のコヌドを䜜成できるこずを心から願っおいたす。

スケゞュヌルの実斜


䜙談は終わり、スケゞュヌルに戻りたす。

Playlist_updateファむル
 #!/bin/bash MUSICDIR=/home/PUBLIC/Music cd $MUSICDIR cp -f $1/playlist.m3u playlist.m3u /root/scripts/radio/shuffle playlist.m3u >> /dev/null echo "$1" > /home/www/HabrFM.ru/genre_non-stop.txt if ps -A | grep ices then killall -HUP ices else /etc/init.d/ices start fi 

最初に、スクリプトは目的のプレむリストファむルを眮き換えおコピヌを実行し、次にランダム化プログラムを起動しお、珟圚のゞャンルをテキストファむルに曞き蟌みたす理由は埌でわかりたす
「プレむリストの再読み蟌み」アむスに信号を送信したす。 以前にicesがシャットダりンした堎合、スクリプトはそれを再床実行したす。 珟圚のトラックの再生が終了したずきにのみ、アむスが新しいプレむリストの再生を開始するこずを知っおおくこずが重芁です。 したがっお、スケゞュヌルはあたり゚レガントに芋えたせんが、友人のクロンに委ねるこずができたす。

私のスタむルの䟋を挙げたす
 crontab -e 58 01 * * * /root/scripts/radio/playlist_update Breaks 58 03 * * * /root/scripts/radio/playlist_update Chill 58 09 * * * /root/scripts/radio/playlist_update Dance 58 14 * * * /root/scripts/radio/playlist_update House 58 17 * * * /root/scripts/radio/playlist_update Trance 58 21 * * * /root/scripts/radio/playlist_update Hardstyle 58 23 * * * /root/scripts/radio/playlist_update Hardcore 

くそヌ これで、予定されおいる攟送の構築が完了したした。 DJがいないずきは、スケゞュヌルどおりにノンストップで挔奏し、DJが珟れるず、リスナヌは自動的に「ブロヌドキャスト」にリダむレクトされたす。 ただし、芚えおいる堎合、サむトに関する未実珟のタスクがただありたす。

音楜デヌタベヌス


そうそう、私は完党に忘れおいたした。 投祚システムを実装するために、MySQLデヌタベヌスを䜿甚したした。 友だちが䞀生懞呜頑匵っおください。

そのため、「ルヌト音楜ディレクトリ」にあるすべおのトラックに関する情報をデヌタベヌスに保存する必芁がありたす。 デヌタベヌスを䜜成する必芁があり私の䟋では、ラゞオです、次の構造を持぀2぀のテヌブルがありたす。

歌の衚
id INT11AUTO_INCREMENT PRIMARY_KEY
ゞャンルVARCHAR15
タむトルVARCHAR100
ファむル名VARCHAR200
レヌトINT11

投祚衚
id INT11
ip VARCHAR16

悲しいこずに぀いお。 第1に、すべおのmp3ファむルラむセンスされおいるものも含むに正しいID3タグがあるわけではなく、ほずんどのファむルにはたったくありたせん。 次に、ファむルからID3タグを読み取るスクリプトが芋぀かりたせんでした。 したがっお、私はいく぀かの犠牲を払わなければなりたせんでした。 ぀たり、TagScannerプログラムを䜿甚しお、すべおのファむルのID3タグを手動で線集し、同じプログラムを䜿甚しお、既に有効なID3タグに埓っおファむルの名前を倉曎したす。 次のテンプレヌトを遞択したした。

<カりンタヌ>。 <アヌティスト>-<䜜曲> .mp3

この蚘事では、このプログラムでの䜜業に぀いおは説明したせん。 UTF-8ではなくすべおのID3タグを保存するこずが基本的に重芁であるずしか蚀えたせん 。 プログラム蚭定には、察応するオプションがありたす。 さらに、すべおの文字「」を、たずえばandに眮き換える必芁がありたす。 プログラムを䜿甚するず、すべおのファむルに察しおこれをすぐに行うこずができたす。

OK、パタヌンに䞀臎する正しいファむル名があり、デヌタベヌスの構造が正しいず仮定したす。 さらに、実際には別のスクリプトですが、既にPHPに含たれおいたすそのため、自由にむンストヌルするこずを忘れないでください。

Db_update.phpファむル
 #!/usr/bin/php <?php $MUSICDIR="/home/PUBLIC/Music"; $hostname = "localhost"; $username = "radio"; //     $password = "12345"; //   $dbName = "radio"; //   mysql_connect($hostname,$username,$password) OR die("Can't connect to database."); mysql_select_db($dbName) or die(mysql_error()); $Gen = array('Dance','House','Trance','Hardstyle','Hardcore','Chill','Breaks','Pumping'); $sql = "SELECT * FROM radio.songs"; $all = mysql_query($sql); $num_before = mysql_num_rows($all); echo "There are $num_before records in database.\n"; echo "\n"; echo "Searching for non-existing file names...\n"; $deleted = 0; while($row = mysql_fetch_array($all, MYSQL_ASSOC)) { $id = $row['id']; $db_filename = $row['Filename']; $exist = @fopen($db_filename,"r"); if (!$exist) { echo "Deleting: [$id] $db_filename\n"; $sql = "DELETE FROM radio.songs WHERE id=$id"; mysql_query($sql); $deleted++; } } if (!$deleted) { echo "Nothing deleted.\n"; } else { echo "Total deleted: $deleted records.\n"; } echo "\n"; $added = 0; echo "Searching for new tracks...\n"; for ($i=0;$i<count($Gen);$i++) { $genre=$Gen[$i]; $fp = fopen("$MUSICDIR/$genre/playlist.m3u","r"); while (!feof($fp)) { $filename = fgets($fp); if (strpos($filename,".mp3")) { $filename = substr($filename,0,strlen($filename)-1); $sql = sprintf("SELECT * FROM radio.songs WHERE Filename='%s'",mysql_real_escape_string($filename)); $res = mysql_query($sql); $num = mysql_num_rows($res); if ($num == 0) { $title = strstr($filename," "); $start = strpos($filename,". ")+2; $len = strpos($filename,".mp3") - $start; $title = substr($filename,$start,$len); $filename = substr($filename,0,strpos($filename,".mp3")+4); $sql = sprintf("INSERT INTO radio.songs ( `id`, `Genre`, `Title`, `Filename`, `Rate` ) VALUES ( NULL, '$genre', '%s', '%s', '0' )", mysql_real_escape_string($title),mysql_real_escape_string($filename)); mysql_query($sql) or die(mysql_error()); $added++; echo "Adding $filename\n"; } } } } if (!$added) { echo "Nothing added.\n"; } else { echo "Total added: $added records.\n"; } echo "\n"; $sql = "SELECT * FROM radio.songs"; $all = mysql_query($sql); $num_after = mysql_num_rows($all); if ($num_before == $num_after) { echo "There are still $num_after records in database.\n"; } else { echo "There are $num_after records in database.\n"; } mysql_close(); ?> 

䞊蚘のスクリプトは、最初に察応するディレクトリになくなったトラックに関するデヌタベヌスからレコヌドを削陀し、次に新しいトラックがあれば远加したす。

プレむリストをコンパむルした盎埌にこのスクリプトを実行するこずは論理的であるため、music_find.shファむルに1行远加したす最初に、パスを独自のパスに眮き換えたす。

 /root/scripts/radio/db_update.php 

珟圚、プレむリストをコンパむルするず、デヌタベヌス内の情報が自動的に曎新されたす。

2番目のテヌブル投祚からおや぀を取りたす。

攟送情報収集


ここでは、特に詳现には觊れたせん。 珟圚のトラックの名前、スタむル、リスナヌの数をテキストファむルに曞き蟌むphpスクリプトに泚目しおください。 これらのファむルは、私たちのサむトのルヌト、぀たり 私の友人であるあなたがWebサヌバヌをむンストヌルしおいない堎合は、急いでむンストヌルしおください。

ファむルicecast_status.php
 #!/usr/bin/php <?php $STATS_FILE = 'http://IP__:_/status.xsl'; $DOCROOT = '/var/www/HabrFM.ru'; //   $hostname = "localhost"; $username = "radio"; //     $password = "12345"; //   $dbName = "radio"; //   mysql_connect($hostname,$username,$password) OR die("Can't connect to database."); mysql_select_db($dbName) or die(mysql_error()); for($i=1;$i<13;$i++) { $fp = fopen($STATS_FILE,'r'); if(!$fp) { die("Unable to connect to Icecast server."); } $stats_file_contents = ''; while(!feof($fp)) { $stats_file_contents .= fread($fp,1024); } fclose($fp); $radio_info = array(); $radio_info['genre'] = ''; $radio_info['listeners'] = ''; $radio_info['now_playing'] = ''; $temp = array(); $search_for = "<td\s[^>]*class=\"streamdata\">(.*)<\/td>"; $search_td = array('<td class="streamdata">','</td>'); if(preg_match_all("/$search_for/siU",$stats_file_contents,$matches)) { foreach($matches[0] as $match) { $to_push = str_replace($search_td,'',$match); $to_push = trim($to_push); array_push($temp,$to_push); } } $radio_info['listeners'] = $temp[5]; $radio_info['now_playing'] = $temp[9]; if(strpos($stats_file_contents,'/live')) { $radio_info['genre'] = "DJ On-Air"; } else { $fp = fopen("$DOCROOT/genre_non-stop.txt","r"); $radio_info['genre'] = fgets($fp); fclose($fp); $radio_info['genre'] = substr($radio_info['genre'],0,strlen($radio_info['genre'])-1); } if ($radio_info['genre'] == "DJ On-Air"){ $rate = "1000+"; } else { $sql = sprintf("SELECT * FROM songs WHERE ( Genre='%s' AND Title='%s' )", mysql_real_escape_string($radio_info['genre']), mysql_real_escape_string($radio_info['now_playing'])); $res = mysql_query($sql) or die(); $row = mysql_fetch_array($res, MYSQL_ASSOC); $rate = $row['Rate']; $id = $row['id']; } $fp = fopen("$DOCROOT/now_playing.txt","w"); fputs($fp,$radio_info['now_playing']); fclose($fp); $fp = fopen("$DOCROOT/id.txt","w"); fputs($fp,$id); fclose($fp); $fp = fopen("$DOCROOT/listeners.txt","w"); if ($radio_info['listeners'] > 0) { fputs($fp,'<span style="color:green; font-weight: bold;">'.$radio_info['listeners'].'</span>'); } else { fputs($fp,'<span style="color:black; font-weight: bold;">'.$radio_info['listeners'].'</span>'); } fclose($fp); $fp = fopen("$DOCROOT/genre.txt","w"); fputs($fp,$radio_info['genre']); fclose($fp); $fp = fopen("$DOCROOT/rate.txt","w"); if ($rate > 0) { fputs($fp,'<span style="color:green; font-weight: bold;">+'.$rate.'</span>'); } if ($rate < 0) { fputs($fp,'<span style="color:red; font-weight: bold;">'.$rate.'</span>'); } if ($rate == 0) { fputs($fp,'<span style="color:black; font-weight: bold;">'.$rate.'</span>'); } fclose($fp); sleep(5); } ?> 


このスクリプトは毎分実行する必芁があり、5秒の遅延で12回実行されたす。 この「バむク」は、友人のクロンが1分未満の時間単䜍の存圚を暗瀺しおいないずいう事実によるものです。 そしお、少なくずも5秒ごずにこの情報を曎新する必芁がありたす。

さお、このスクリプトを毎分実行するように最埌にCronに䟝頌しおください。

 crontab -e */1 * * * * /root/scripts/radio/icecast_status.php 

OK、今私たちのサむトのルヌトにはすでに5぀の玠晎らしいファむルがありたす
•now_playing.txt-珟圚のトラックのアヌティストず名前。
•id.txt-珟圚のコンポゞションのデヌタベヌス内の䞀意の番号。
•genre.txt-ノンストップで再生しおいる堎合はトラックのスタむル、DJが攟送䞭の堎合は「DJ On-Air」のラむン。
•listeners.txt-リスナヌの数HTML圢匏を考慮0より倧きい堎合は緑、れロの堎合は緑-黒。
•rate.txt-評䟡を远跡したすHTML圢匏も考慮に入れたす。

うわヌ、私たちは私たちが欲しかったものたたは私が欲しかったものをほずんど手に入れたした。 投祚を実斜し、実際にサむトに必芁な情報を衚瀺するこずが残っおいたす。

歌に投祚する


投祚を実装したいずきに最初に考えたのは、1぀のトラックの繰り返し投祚をブロックする方法でしたか クッキヌは通垞䜿甚されたすが、私はそれらを䜿甚したこずはなくそうです、これも起こりたす、IPアドレスでブロックするこずにしたした。 したがっお、votesテヌブルにはidずipの2぀のフィヌルドしかありたせん。

ファむルvote.phpサむトのルヌトに配眮する必芁がありたす
 <?php //, ,     $DOCROOT = '/var/www/HabrFM.ru'; $hostname = "localhost"; $username = "radio"; $password = "12345"; $dbName = "radio"; mysql_connect($hostname,$username,$password) OR die("Can't connect to database."); mysql_select_db($dbName) or die(mysql_error()); $fp = fopen("$DOCROOT/id.txt", "r"); $id = fgets($fp); fclose($fp); $sql = sprintf("SELECT * FROM votes WHERE ( id='%s' AND ip='%s' )", $id, mysql_real_escape_string($_SERVER['REMOTE_ADDR'])); $res = mysql_query($sql); $num = mysql_num_rows($res); if ($num == 0) { $type = $_GET['type']; if ($type == 'plus') { $sql = sprintf("UPDATE songs SET Rate=Rate+1 WHERE id='%s'", $id); } else { if ($type == 'minus') { $sql = sprintf("UPDATE songs SET Rate=Rate-1 WHERE id='%s'", $id); } else { die('Irregular argument.'); } } if (mysql_query($sql)) { $sql = sprintf("INSERT INTO votes (`id`, `ip`) VALUES ('%s', '%s')", $id, mysql_real_escape_string($_SERVER['REMOTE_ADDR'])); mysql_query($sql); echo '  .'; } else { echo ' .'; } } else { echo "     ."; } mysql_close(); ?> 


このスクリプトは、1぀のパラメヌタヌ-投祚のタむプ賛成たたは反察を取りたす。 したがっお、呌び出し
 vote.php?type=plus 

珟圚のトラックに1぀の評䟡を远加したす。
 vote.php?type=minus 

1぀の評䟡を奪いたす。

サむトの情報を衚瀺する


だから、投祚がありたす。 おそらく、サむトに必芁なすべおの情報を衚瀺するために残っおいたす。 特定のHTMLコヌドは提䟛したせん。 すばらしいjQueryフレヌムワヌクの存圚を突然忘れおしたった堎合は、思い出させおください。

HTMLコヌドの適切な堎所に、トラック名にid = 'now_playing'、ゞャンルにid = 'genre'などの芁玠があるようにしたす。
次に、次の呌び出しに埋め蟌むず䟿利ですもちろん、jQueryラむブラリをサむトディレクトリに远加しお接続する必芁がありたす。
 <script> function show() { $.ajax({ url: "now_playing.txt", cache: false, success: function(html){ $("#now_playing").html(html); } }); $.ajax({ url: "genre.txt", cache: false, success: function(html){ $("#genre").html(html); } }); $.ajax({ url: "listeners.txt", cache: false, success: function(html){ $("#listeners").html(html); } }); $.ajax({ url: "rate.txt", cache: false, success: function(html){ $("#rate").html(html); } }); } $(document).ready(function(){ show(); setInterval('show()',5000); }); </script> 


そしお、5秒ごずにペヌゞの情報が曎新されたすさらに、ペヌゞをリロヌドするこずなく。

蚘事の冒頭で、TOP20ランキングを発衚したこずを芚えおいたすか はい、それは玠晎らしいこずです。

そのため、特定のスタむル/ゞャンルのベストタむプ= 1たたはワヌストタむプ= 2トラックのテヌブルを次の圢匏で生成する最埌のスクリプト
| 構成| 評䟡|

ファむルtop20.phpりェブサむトでツヌルを終了するこずをお勧めしたす
 <?php $Gen = array('Dance','House','Trance','Hardstyle','Hardcore','Chill','Breaks','Pumping'); //    :) $hostname = "localhost"; $username = "radio"; $password = "12345"; $dbName = "radio"; mysql_connect($hostname,$username,$password) OR die("Can't connect to database."); mysql_select_db($dbName) or die(mysql_error()); $genre = $_GET["genre"]; $type = $_GET["type"]; echo "<br>\n"; if (!(in_array($genre,$Gen))) { die("Irregular argument."); } $sql = sprintf("SELECT Title, Rate FROM songs WHERE (Genre='%s'",mysql_real_escape_string($genre)); if ($type==1) { $sql = $sql . " AND Rate>0) ORDER BY Rate DESC LIMIT 20"; } else if ($type==2) { $sql = $sql . " AND Rate<0) ORDER BY Rate ASC LIMIT 20"; } else { die("Irregular argument"); } $res = mysql_query($sql); if (mysql_num_rows($res)>0) { echo '<table border="1" style="font-family: Verdana,Geneva; font-size: 10;" cellspacing="0" width="100%">'; echo "\n"; echo '<tr><td align="left">№</td><td align="left" width="100%"> - </td><td align="right"></td></tr>'; echo "\n"; } else { echo "   .     -       ."; } $i = 1; while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) { echo "<tr>"; echo '<td align="left">' . $i . '.</td>'; echo '<td align="left">' . $row['Title'] . '</td>'; echo '<td align="right">' . $row['Rate'] . '</td>'; echo "</tr>\n"; $i++; } if (mysql_num_rows($res)>0) { echo '</table>'; } mysql_close(); ?> 

以䞊です。 次に、このスクリプトをHTMLコヌドの適切な堎所に埋め蟌む必芁がありたす同じjQueryはsetInterval 'show'、5000なしでのみ䜿甚できたす。しかし、これは私の友人であるあなたに宿題ずしお任せたす。

私の話があなたにずっお有甚であるか、単に興味深いものになるこずを心から願っおいたす。

Source: https://habr.com/ru/post/J131116/


All Articles