Showing posts with label Web Design. Show all posts
Showing posts with label Web Design. Show all posts

Sunday, 29 December 2019

YouTube Videos part 2

Having now set up an IIS/ASP server, now it is time to use it to set up your YouTube videos.
As noted in the previous post, ASP files comprise conventional HTML combined with server side Javascript code.

The JavaScript functions can be in separate included files. This allows the code to be easily reused.
The calls to the functions can then be made within the main file as required:

<% videolist="I68GG96bSYQ:Christmas lights,I68GG96bSYQ:More Chrismas,I68GG96bSYQ:Not Christmas";
Response.Write(makebuttons(videolist));
Response.Write(makeplaylist(videolist));

Server Side Functions

Create a file called makebuttons.asp.
There are three functions.
The first one assembles a button similar to that in the previous post.
The second takes a list of Youtube video IDs and their titles and assembles a button for each of the pairs.
The third function assembles the same list into YouTube playlists.
<%
function makebutton(index,buttonsource,playsource,buttonID,videotitle){
   result="";
   result=result +"<div class='videobuttoncontainer'>";
   result=result +"<img src='" +buttonsource+"' alt='Title' class='image' width='100%' onclick='setPlayList("+index.toString()+")' />";
   result=result +"<div class='videobuttonoverlay'>";
   result=result +"<img class='videobuttonicon' src='"+playsource+"' id='"+buttonID+"' onclick='setPlayList("+index.toString()+")' alt='"+videotitle+"' title='Play video: "+videotitle+"' oncontextmenu='copytoClipboard("+index.toString()+")' />";
   result=result +"</div>";
   result=result +"<span id='buttontext' class='buttontext'>"+videotitle+"</span>";
   result=result +"</div>";
   return result;
}
function makebuttons(videolist){
   result="";
   videos=videolist.split(",");
   for(ix =0;ix<videos.length;ix++){
  videoitem=videos[ix].split(":");
  result=result+makebutton(ix,"assets/button.png","assets/play.png", videoitem[0],videoitem[1]);
   }
   return result;

}
function makeplaylist(videolist){
   result="";
   videos=videolist.split(",");
   videoitem=videos[0].split(":");
   result=result+"'" +  videoitem[0]+"?playlist=";
   for(ix =1;ix<videos.length;ix++){
  videoitem2=videos[ix].split(":");
  result=result+','+videoitem2[0]
   }
   result=result+"'";
   for(ix =1;ix<videos.length;ix++){
  videoitem=videos[ix].split(":");
  result=result+",'" +  videoitem[0]+"?playlist=";
  for(iy =ix;iy<videos.length;iy++){
 videoitem2=videos[iy].split(":");
 result=result+','+videoitem2[0]
  }
  for(iy =0;iy<ix;iy++){
 videoitem2=videos[iy].split(":");
 result=result+','+videoitem2[0]
  }
  result=result+"'";
   }
   result="<script>playlists=["+result+"]</script>";
   return result;
}
%>

New Client Side functions

There are two pieces of code that will be used client side. The first is effectively the same as that used in the client side example. The second piece sets up a capability to copy the path to the video within the page to the clipboard.
<script>

function setPlayList(aPlaylist){
//alert(playlists[aPlaylist]);
youtubePlayer = document.getElementById("youtube_video");
youtubePlayer.src="https://www.youtube.com/embed/"+playlists[aPlaylist] + "&rel=0&autoplay=1";
}

function copytoClipboard(videonum){
result=window.location.href;
hashbit="";
querybit="";
newquery="";
starthash = result.indexOf("#");
startquery=result.indexOf("?");
if(starthash>0){
hashbit=result.slice(starthash);
result=result.substring(0,starthash)
 }
 else{
 hashbit="#demo";
 }
if(startquery>0){
querybit=result.slice(startquery).slice(1);
querybits=querybit.split("&");
result=result.substring(0,startquery)
foundVideo=false;
for(ix=0;ix<querybits.length;ix++){
endname=querybits[ix].indexOf("=");
if(querybits[ix].substring(0,endname)=="video"){
newquery=newquery+"video="+videonum.toString() +"&";
foundVideo=true;
}
else{
newquery=newquery+querybits[ix] +"&";
}
}
if (!foundVideo){
newquery=newquery+"video="+videonum.toString() +"&";
}
if(newquery.length>0){
newquery=newquery.slice(0,newquery.length-1);
}
result=result+"?"+newquery;

}
else{
result=result+"?video="+videonum.toString();
}
result=result+hashbit;
var copything=document.getElementById("copything")
copything.value=result;
copything.select();
copything.setSelectionRange(0, 99999);
}
</script>

The Main ASP file

The main ASP file is modified from the original:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
.videoWrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.videoWrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.videoDisplay {
float: left;
width: 85%;
}
.videoList {
float: left;
width: 15%;
opacity:1;
}

.videobuttoncontainer {
position: relative;
width: 100%;
max-width: 400px;
}
.videobuttonoverlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0.25;
transition: .3s ease;
}

.videobuttoncontainer:hover .videobuttonoverlay:hover {
background-color: red;
opacity: 0.8;
color: white;
}
.videobuttonicon {
color: white;
font-size: 100px;
position: absolute;
top: 30%;
left: 40%;
width:25%;
height:auto;
text-align: center;
}
.buttontext{
opacity:1.0;
position:absolute;
bottom:4px;
left: 4px;
font-size: small;
color:white;
}
.buttontext:hover{
color:white;
}

</style>
<!-- #include file="makebuttons.asp" -->
<!-- #include file="makebuttons_clientside.asp"-->
</head>
<body>
<table width="100%">
<tr>
<th border="1" width="5%"></th>
<th border="1">
Test stuff
</th>
<th  width="5%">

</th>
</tr>
<tr>
<td>Ignore this</td>
<td border="1">
<div class="row">
<div class="videoList">
<% videolist="I68GG96bSYQ:Christmas lights,I68GG96bSYQ:More Chrismas,I68GG96bSYQ:Not Christmas";
Response.Write(makebuttons(videolist));
Response.Write(makeplaylist(videolist));
%>
<input type="text" value="Hello" id="copything">
</div>
 </div>
   <div class="videoDisplay">
 <div class="videoWrapper">
<iframe  id="youtube_video"
src="https://www.youtube.com/embed/I68GG96bSYQ"
frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen>
</iframe>
</div>
</div>
</div>
</td>
<td>Ignore this</td>
</tr>
</table>
</body>
</html>

When browsed to, the result is as follows:

Tuesday, 15 October 2019

YouTube Videos

Programmed YouTube Video viewer

Youtube takes a lot of the effort out of hosting and displaying videos. If you are happy for Google to have access to the information about who is watching your videos, then it makes sense to use them to host them.

One problem is making it easy to control how the videos are displayed and allow the viewer to select what they want to watch.

Server Side

For later.

Client Side

It is a matter of Style

Getting the video to display properly, especially if you are using a responsive style web site is a bit more complicated than Google makes out, as the default height is about 150 pixels, which is a bit embarrassing.

The solution from CSS-Tricks based on work by Thierry Koblentz sets the height as a percentage of the width. When the page resizes, the height is recalculated. Any IFRAME inside it is scaled to 100% to fill the container.

.videoWrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
}
.videoWrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
The next bit is getting the play button to hover over the images.
  .container {
  position: relative;
  width: 100%;
  max-width: 400px;
  }
  .overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100%;
  width: 100%;
  opacity: 0.25;
  transition: .3s ease;
  }

  .container:hover .overlay {
  background-color: red;
  opacity: 0.8;
  }
  .icon {
  color: white;
  font-size: 100px;
  position: absolute;
  top: 30%;
  left: 40%;
  width:25%;
  height:auto;
  text-align: center;
}

The Buttons

The buttons are contained in two nested div objects.
The first (of class 'container') holds the YouTube thumbnail image.
The second (of class 'overlay') holds the play button image and has the onclick event handler described below.
<div class="container">
   <img src=http://i1.ytimg.com/vi/xxxxxxxxxxx/mqdefault.jpg 
     alt="Title" class="image" width='100%' />
   <div class="overlay">
     <img class="icon" src="play.png" onclick='setPlayList(1)'/ >
   </div>
</div>
The overlay has a normal opacity of 0.25, so the button image displays faintly. When the mouse hovers over the image, the background changes to red and the opacity increases to 0.8.

Video Selection

The video choice requires an array containing the video to play plus a rotating set of the other videos. That is a coding exercise for server side and another time.
<script>
playlists =['xxxxxx?playlist=yyyyy,zzzzz', 'yyyyy?playlist=zzzzz,xxxxx'];
 </script>

Each play button has an onclick event that calls the setPlayList function with a number which selects the element from the array described above.
<script>
function setPlayList(aPlaylist){
youtubePlayer = document.getElementById("youtube_video");
youtubePlayer.src="https://www.youtube.com/embed/"+playlists[aPlaylist] + "&rel=0&autoplay=1";
}
</script>

The autoplay parameter starts the video playing, the rel = 0 prevents videos from other channels from being displayed,

References

https://support.google.com/youtube/answer/171780?hl=en
https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php
https://alistapart.com/article/creating-intrinsic-ratios-for-video/

Saturday, 16 February 2019

Python Web Scraper

Search Engine Optimisation is a mysterious skill, the companies behind search engines do not want to make it easy to play their engines to force certain pages to the top of the results list.

However, one of the things that is listed as being useful is the presence of the key search words in the body of the HTML page.

The following is a simple Python script that retrieves the text from a supplied URL creates a searchable tree using LXML, extracts the text and then counts the occurrences of non numeric words longer than three characters.

# Functions to scrape the body text from a web page
# and return the top 10 occurring words
# Currently does not play well with HTML comments

# Also note that the order of the printed results is subject to change,
# this can be important if there are more than one element with the
# same occurrence as the last element displayed 

from lxml import html
import requests
import re
import collections

noisewords=['at','and','an','the','we','to','is','of','by','not','in','as','be','or','for']
def testgoodword(astring):
    if astring.strip() in noisewords:
        return False
    else:
        return True

def webscrape(aURL):

# Get the page from the URL
    page = requests.get(aURL)
# Make an HTML tree from the text
    tree = html.fromstring(page.content)

# Extract non script and non style text from the HTML tree
    bodytext=""
    for  elt in tree.getiterator():
        if elt.text is not None:
            if elt.tag!="script" and elt.tag!="style":
                if elt.text.strip()!='':
                    bodytext=bodytext+' '+elt.text
                    
# Define a regular expression to extract words
# (one or more alphanumerics followed by white space character)
    p = re.compile(r'\w\w+\s')

# Use a Counter collection to record the occurrences (the word is the key)
# Counter collections return zero if there is no element with a supplied key
    c = collections.Counter()

# Iterate through the "words2 found by the regular expression
    iterator=p.finditer(bodytext)
    for match in iterator:
        testword=match.group().strip().lower()
        if not testword.isnumeric():        # Ignore numbers
            if testgoodword(testword):      # Only use non noise words
                c[testword]+=1

    return c

# Print the most common words
def print_webscrape(c):
    print ('Most common:')
    for word, count in c.most_common(10):
        print ('\'%s\': %7d' % (word, count))

# Testing code 
if __name__ == "__main__":
    # execute only if run as a script
    c=webscrape("https://en.wikipedia.org/wiki/Python_(programming_language)")
    print_webscrape(c)


Most common:
'python':     189
'retrieved':     127
'programming':      49
'software':      35
'language':      29
'edit':      29
'with':      29
'pep':      26
'languages':      24
'march':      23
>>> 
Most common:
'python':     189
'retrieved':     127
'programming':      49
'software':      35
'edit':      29
'language':      29
'with':      29
'pep':      26
'languages':      24
'march':      23
>>> 
Note the order of "edit", "language" and "with" alter. If you really want the top ten, you need to expand the range until the you have a different count.
Most common:
'python':     189
'retrieved':     127
'programming':      49
'software':      35
'with':      29
'language':      29
'edit':      29
'pep':      26
'languages':      24
'march':      23
'february':      23
'org':      23
'from':      21
'van':      20
'december':      18
A you can see, there are three results with a count of 23. The Counter.most_common() function will return them in a random order

References



Monday, 22 October 2018

Browser size - Javascript

Sometimes when you are building a web page it is useful to know what the browser size is, so you check it will display correctly if it is on a desk top, lap top, tablet or mobile.

The following Javascript will put the browser client size as the title.
<html>
<head>
    <script>
        function titleIsSize() {
            document.title = "" + document.body.clientWidth + " pixels.";           
        }
    </script>
</head>
<body  onresize="titleIsSize()"  >
</body>
</html>