Youtube Video Downloader This code takes a YouTube video and download it. It supports only non-copyrighted videos due to YouTube's new algorithms. 

Any thoughts about the structure and the logic? I would like to learn from my mistakes, I've just started coding with python.

#!/usr/bin/env python3.5.2

import urllib.request, urllib.parse
import os


def main():
    """
    This code will download only non copyrighted youtube videos due to the new algorithms for accessing video files taht Youtube had changed. 
    Instead of "token" they now use "signature" variable, and "signature" seems to be dependent on either cookie-stored data or IP address of the client
    """
    print("\n                          * * * * * * * * * * * * * * *")
    print("                          *                           *")
    print("                          * Youtube Video Downloader! *")
    print("                          *                           *")
    print("                          * * * * * * * * * * * * * * *\n")
    # make sure to change directory path
    directory = r'C:\Users\SalahGfx\Desktop\DownloadedVideos'

    def get_sourcecode(url):
        return urllib.request.urlopen(url).read()

    def get_info():
        return urllib.parse.parse_qs(get_sourcecode(url).decode('unicode_escape'))

    def get_video_title_path():
        try:
            return os.path.join(directory, '{}.mp4'.format(get_info()['title'][0]))

        except KeyError:
            print('Parsing error, please rerun the code!')

    def get_stream_map():
        return get_info()['url']

    def get_stream_map_list():
        video_links = []
        for video_stream in get_stream_map():
            if "googlevideo" == video_stream.split('/')[2].split('.')[1]:
                video_links.append(video_stream)

            else:
                pass
        return video_links

    def validate_url(url):
        return url.startswith('https://www.youtube.com/')

    def download_video(k):
        return urllib.request.urlretrieve(get_stream_map_list()[k], get_video_title_path())

    def download_hq_video(quality):
        k = 0
        download_video(k)
        print("Downloading {} -----------&gt; {} in {} quality.".format(get_stream_map_list()[k], get_video_title_path(),
                                                                     quality))

    def download_md_video(quality):
        k = 1
        download_video(k)
        print("Downloading {} -----------&gt; {} in {} quality.".format(get_stream_map_list()[k], get_video_title_path(),
                                                                     quality))

    def download_sm_video(quality):
        k = 2
        download_video(k)
        print("Downloading {} -----------&gt; {} in {} quality.".format(get_stream_map_list()[k], get_video_title_path(),
                                                                     quality))

    while True:
        try:
            url, quality = input(
                "Please type a youtube video url and its quality(choose between high, medium and small) and separate them with a space: ").split()

        except ValueError:
            print("Please type the right url and quality.");
            print("Make sure the url start with 'https://www.youtube.com/'");
            print("high - for downloading high quality video");
            print("medium - for downloading medium quality video");
            print("small - for downloading small quality video");
            continue

        if validate_url(url) and quality == 'high':
            get_sourcecode(url)
            download_hq_video(quality)
            break

        elif validate_url(url) and quality == 'medium':
            get_sourcecode(url)
            download_md_video(quality)
            break

        elif validate_url(url) and quality == 'small':
            get_sourcecode(url)
            download_sm_video(quality)
            break

        else:
            break

if __name__ == '__main__':
    main()
I don't see why you want/need three functions to download the different quality videos. There is a bunch of repeated logic both in the functions and in the main loop.

Then, I would move all of the main specific code into the __name__ == __main__ section because that's the purpose of that section. 

#!/usr/bin/env python3.5.2

import urllib.request, urllib.parse
import os

def get_sourcecode(url):
    return urllib.request.urlopen(url).read()

def get_info():
    return urllib.parse.parse_qs(get_sourcecode(url).decode('unicode_escape'))

def get_video_title_path():
    try:
        return os.path.join(directory, '{}.mp4'.format(get_info()['title'][0]))
    except KeyError:
        print('Parsing error, please rerun the code!')

def get_stream_map_list():
    video_links = []
    for video_stream in get_info()['url']:
        if "googlevideo" == video_stream.split('/')[2].split('.')[1]:
            video_links.append(video_stream)
    return video_links

quality_map = {'small': 0, 'medium': 1, 'high': 2}

def download_video(quality='medium'):
    k = quality_map.get(quality)
    map_list = get_stream_map_list()[k]
    title_path = get_video_title_path()

    print("Downloading {} -----------&gt; {} in {} quality.".format(map_list, title_path, quality))
    return urllib.request.urlretrieve(map_list, title_path)


if __name__ == '__main__':
    print("\n                          * * * * * * * * * * * * * * *")
    print("                          *                           *")
    print("                          * Youtube Video Downloader! *")
    print("                          *                           *")
    print("                          * * * * * * * * * * * * * * *\n")
    # make sure to change directory path
    directory = r'C:\Users\SalahGfx\Desktop\DownloadedVideos'

    while True:
        try:
            url, quality = input(
                "Please type a youtube video url and its quality(choose between high, medium and small) and separate them with a space: ").split()

        except ValueError:
            print("Please type the right url and quality.");
            print("Make sure the url start with 'https://www.youtube.com/'");
            print("high - for downloading high quality video");
            print("medium - for downloading medium quality video");
            print("small - for downloading small quality video");
            continue

        if url.startswith('https://www.youtube.com/') and quality in quality_map:
            get_sourcecode(url)
            download_video(quality)
            break