0

I am creating a website that gets random videos from the db. My problem is that my code to get the random video is this:

select id,content from videos order by rand() limit 1

And I don't want the user to see the same video until 3 other videos (at least) were played before.

Do you have any suggestion on how to do that? This is how my site works currently.

  1. HTML-AJAX(CALL FOR VIDEO URL)
  2. PHP(RETURN RANDOM VIDEO URL) One video.
  3. AJAX(DISPLAY VIDEO)

[EDITED] Another problem I am facing is that I need to return only one video url, because this is how my ajax call look like:

success: function(data){

            $('#content').html('<div id="ytapiplayer">You need Flash player 8+ and JavaScript enabled to view this video.</div>');
            var params = { allowScriptAccess: "always" };
            var atts = { id: "ytapiplayer" };
            swfobject.embedSWF(data.vidData+"&enablejsapi=1&playerapiid=ytapiplayer?autoplay=1", "ytapiplayer", "500", "405", "8", null, null, params, atts);
}

Thanks in advance.

Harry B
  • 2,864
  • 1
  • 24
  • 44
funerr
  • 7,212
  • 14
  • 81
  • 129
  • In that case you need to remember the video's selected prior in a (temp) table and test to see if no duplicate was selected. – Johan Aug 31 '11 at 11:11
  • 3
    NEVER use order by rand(). It is a performance killer! – Rijk Aug 31 '11 at 11:13
  • @Rijk van Wel, So what should I use? – funerr Aug 31 '11 at 11:21
  • Here's an alternative (found using Google): http://stackoverflow.com/questions/1244555/how-can-i-optimize-mysqls-order-by-rand-function – Rijk Aug 31 '11 at 11:24

2 Answers2

1

Could the video id be sent to the client? Then from there the client (Javascript) request the video. Here how that could be played:

  1. Ajax the the list of video ids
  2. insert them in an Array in javascript (var toWatch)
  3. Random the array
  4. Get the first video
  5. Remove the id from the first array. You might want to keep a trace of that id in an other array
  6. repeat 4-5

In javascript it might look like :

$.post("getVideoId.php",function(videoId){
   var aVideoToWatch = videoId.split(',').sort(randOrd);

   for(var x=0; x<aVideoToWatch.length;x++){
       $.post("getAVideo(aVideoToWatch[x])",function(){
           //play the video
       })
   }
})

// source : http://javascript.about.com/library/blsort2.htm
function randOrd(){
 return (Math.round(Math.random())-0.5); }
David Laberge
  • 15,435
  • 14
  • 53
  • 83
  • Yes the video id is sent actually(echo json_encode(array("id" => $random_vid[0], "vidData" => $random_vid[1]));). tried the same things with cookies, but it didn't work... And what do you mean by:"Ajax the list of video"? what list? what is the role of the php? return what? – funerr Aug 31 '11 at 11:15
  • Do not use cookie, if you are in ajax do not refresh the page. Use dialog in stead. Like imbd. – David Laberge Aug 31 '11 at 11:17
  • Whats a dialog? (And I edited my question could you answer it please?) – funerr Aug 31 '11 at 11:19
  • So getVideoid.php should output about 5 videos each ajax call, and then repeat the js section? – funerr Aug 31 '11 at 11:25
  • At this point it is your call. It can get all the video or only the latest 5. This is jsut a very rought example. – David Laberge Aug 31 '11 at 11:27
  • Yes, (main question edited), I can return only one video url from php ...look at my question. (thanks) – funerr Aug 31 '11 at 11:37
  • I have manipulated the code, but I used the basic idea, Thank you! – funerr Aug 31 '11 at 16:03
1

You could just use (We'll grab fifteen so we don't have to query the server so much):

SELECT id, content FROM videos ORDER BY RAND() LIMIT 15

Hand those fifteen to the browser and allow it to request the videos. Once it has seen the fifteen, it can ask the server for three more. It can skip ones it's already played by storing played video ids.

If you are delivering results via Ajax and JSON you can just return the concatenation of the results arrays:

<?php
$query = $pdo->query('SELECT id, content FROM videos ORDER BY RAND() LIMIT 10');
$videos = $query->fetchAll();
echo json_encode($videos);
?>

Then in JS:

(function playRandomVideos() {  //Closures are cool
    $.getJSON('getRandomVideos.php', {success: function(videos) {
        for(video in videos) {
            if(video.id in playRandomVideos.played) {
                continue;
            }
            play(video);
            playRandomVideos.played.push(video.id);
        }
        playRandomVideos();
    }});
})();
playedRandomVideos.played = [];
Bailey Parker
  • 15,599
  • 5
  • 53
  • 91
  • So you mean: 1)SELECT id, content FROM videos ORDER BR RAND() LIMIT 3 2)SELECT id, content FROM videos ORDER BR RAND() LIMIT 3,3 3)SELECT id, content FROM videos ORDER BR RAND() LIMIT 6,3 and so on...? And what is the BR standing for? – funerr Aug 31 '11 at 11:23
  • `BR` was a typo of `BY`. I am suggesting that if you query the DB for three videos at a time, they will be unique because `ORDER BY` will return all rows without duplicates. So yes, I think you understand me correctly. – Bailey Parker Aug 31 '11 at 11:26
  • Yes but something like this could happen: generation one: 6,11,9 then generation two: 9,4,6 and that will display the video id 9 twice right after the first generation, I have tested that. – funerr Aug 31 '11 at 11:33
  • My mistake, you can fix this. Give me a minute to update my JS. – Bailey Parker Aug 31 '11 at 11:37
  • Thanks for the time and thought you put into this, but I had better understanding of @David Laberge solution. Thanks anyways, I really appreciate it! (; – funerr Aug 31 '11 at 16:05