Golang Project Structure

Tips and tricks for writing and structuring Go code

Lux Makes Downloading Videos Extremely Easy

Language

  • unknown

by

Have you ever been watching a video and wanted to download it, so you can watch it again offline or on another device?

I’m going to show you something that should be able to help you do just that: Lux is a really handy little command-line application that has been built in Go and it makes downloading videos from the internet simple.

A dimly lit lightbulb hanging from the ceiling, shown against the bare wall of a room.
The name Lux comes from the Latin word for “light”. Physicists also use the word lux to refer to a standard unit of illuminance: an average lightbulb emits between 30 and 100 lux.

You don’t even need to open a web-browser window, if you don’t want to view the videos before you download them, so you can also use Lux to download videos on systems, like servers or single-board computers, that don’t have a desktop installed.

Installing Lux

If you have the Go toolchain set up on your system already, it couldn’t be easier to download and install Lux.

(If you’ve come to this page from a search engine and you don’t actually know anything about the Go programming language but you do want to download videos with Lux, you can install Go very easily and it’ll help you to follow along with the rest of this post, even if you never actually do any programming of your own.)

All you need to do is run the following command and Lux‘s binary file will be installed (within the path given by the $GOBIN environment variable):

go install github.com/iawia002/lux@latest

Otherwise you can use Homebrew on Mac OS or Scoop on Windows to install Lux. Just run brew install lux or scoop install lux and let one of those package managers deal with the installation for you.

Please note that you must also have the ffmpeg tool installed on your computer, since Lux uses this to process and encode the videos. You can download it from the official website or by using your computer’s package manager.

I am not a lawyer, so I am not qualified to give an informed opinion on legal rights and restrictions in any jurisdiction, but, needless to say, it may not be legally permissible to download videos from some websites or popular video-streaming services. I do not know about the rights and wrongs of any particular case, but you should always seek expert advice from someone who does know, if you’re unsure.

A statue of Lady Justice, also known as Justicia. She symbolizes the importance of law and order.
Lady Justice, a traditional personification of law and order. She is blindfolded to symbolize that a society’s rules should be applied equally to everyone. This is, of course, an ideal that doesn’t always happen in practice.

This post is not meant to encourage you to do anything that could be against the terms and conditions of any service or website. I believe in the free flow of information, where practicable and possible, but I also believe that creators should be fairly rewarded for their work. However, I know that it’s not always easy to reconcile these two goals, so it’s important to make sure that you comply with the law.

For the purposes of demonstration, I will err on the side of caution: I will be using a public-domain video hosted by the United States National Park Service (NPS).

Choosing a Video to Download

Now that the little legal disclaimer’s out of the way, let’s get down to business.

I have chosen to download a video hosted by the NPS that shows an aerial view of the Grand Canyon, one of the natural wonders of the world. The video lasts for less than a minute, and it shows the beauty of the majestic landscape, which was gradually formed as the Colorado River carved its way through the sandstone and mudstone rock over many thousands of years.

A screenshot from the video of the Grand Canyon that we are going to download using the Lux tool.
The Grand Canyon is located in the state of Arizona and it is one of the most visited tourist sites in the entire United States of America.

If Lux has been installed properly onto your system, you should be able to access the tool simply by typing the word lux at the command line. You can check what version of the tool is installed by running the following command:

lux --version

On my system, this produces the following output:

lux: version v0.12.0, A fast and simple video downloader.

Getting Some Information Before We Decide to Download

It looks like it’s up and running, so let’s get some information about the video showing the Grand Canyon that we want to download. We just need to give the video’s URL while also specifying the -i option, which stands for “information”, like so:

lux -i https://www.nps.gov/nps-audiovideo/legacy/grca/B6D01994-155D-451F-679C4406F71D1006/grca-desertviewrimcountrytiltup_480x270.mp4

This command produced the following output for me:

 Site:      Universal
 Title:     grca-desertviewrimcountrytiltup_480x270
 Type:      video/mp4
 Streams:   # All available quality
     [default]  -------------------
     Quality:         default
     Size:            1.40 MiB (1468967 Bytes)
     # download with: lux -f default ...

This gives us information about the video’s filetype, which we probably could have guessed from the .mp4 extension anyway, but it also tells us how big the file’s size is in megabits, which is useful to know, as we can estimate how long the video will take to download — or we could decide not to download it at all, if it’s extremely large.

Getting Some More Information

If you run the previous command using the URL of a video that has multiple streams available, you will usually see even more information provided. For example, the following information was provided when I gave the command the URL of a video containing classical music:

 Title:     Camille Saint-Saëns – Danse Macabre, Dance of Death Op.40
 Type:      video
 Streams:   # All available quality
     [248]  -------------------
     Quality:         1080p video/webm; codecs="vp9"
     Size:            129.77 MiB (136072076 Bytes)
     # download with: lux -f 248 ...

     [137]  -------------------
     Quality:         1080p video/mp4; codecs="avc1.640028"
     Size:            121.47 MiB (127375533 Bytes)
     # download with: lux -f 137 ...

     [399]  -------------------
     Quality:         1080p video/mp4; codecs="av01.0.08M.08"
     Size:            119.71 MiB (125526536 Bytes)
     # download with: lux -f 399 ...

     [136]  -------------------
     Quality:         720p video/mp4; codecs="avc1.4d401f"
     Size:            78.12 MiB (81916865 Bytes)
     # download with: lux -f 136 ...

     [247]  -------------------
     Quality:         720p video/webm; codecs="vp9"
     Size:            77.00 MiB (80745006 Bytes)
     # download with: lux -f 247 ...

     [398]  -------------------
     Quality:         720p video/mp4; codecs="av01.0.05M.08"
     Size:            69.80 MiB (73188072 Bytes)
     # download with: lux -f 398 ...

     [135]  -------------------
     Quality:         480p video/mp4; codecs="avc1.4d401e"
     Size:            50.51 MiB (52962873 Bytes)
     # download with: lux -f 135 ...

     [244]  -------------------
     Quality:         480p video/webm; codecs="vp9"
     Size:            47.59 MiB (49905454 Bytes)
     # download with: lux -f 244 ...

     [18]  -------------------
     Quality:         360p video/mp4; codecs="avc1.42001E, mp4a.40.2"
     Size:            40.44 MiB (42405739 Bytes)
     # download with: lux -f 18 ...

     [397]  -------------------
     Quality:         480p video/mp4; codecs="av01.0.04M.08"
     Size:            39.65 MiB (41572593 Bytes)
     # download with: lux -f 397 ...

     [134]  -------------------
     Quality:         360p video/mp4; codecs="avc1.4d401e"
     Size:            31.76 MiB (33299942 Bytes)
     # download with: lux -f 134 ...

     [243]  -------------------
     Quality:         360p video/webm; codecs="vp9"
     Size:            30.63 MiB (32120934 Bytes)
     # download with: lux -f 243 ...

     [396]  -------------------
     Quality:         360p video/mp4; codecs="av01.0.01M.08"
     Size:            25.85 MiB (27105481 Bytes)
     # download with: lux -f 396 ...

     [242]  -------------------
     Quality:         240p video/webm; codecs="vp9"
     Size:            20.19 MiB (21173992 Bytes)
     # download with: lux -f 242 ...

     [133]  -------------------
     Quality:         240p video/mp4; codecs="avc1.4d4015"
     Size:            19.25 MiB (20187321 Bytes)
     # download with: lux -f 133 ...

     [395]  -------------------
     Quality:         240p video/mp4; codecs="av01.0.00M.08"
     Size:            16.92 MiB (17739461 Bytes)
     # download with: lux -f 395 ...

     [278]  -------------------
     Quality:         144p video/webm; codecs="vp9"
     Size:            14.65 MiB (15356740 Bytes)
     # download with: lux -f 278 ...

     [160]  -------------------
     Quality:         144p video/mp4; codecs="avc1.4d400c"
     Size:            13.43 MiB (14078058 Bytes)
     # download with: lux -f 160 ...

     [394]  -------------------
     Quality:         144p video/mp4; codecs="av01.0.00M.08"
     Size:            12.49 MiB (13096371 Bytes)
     # download with: lux -f 394 ...

     [251]  -------------------
     Quality:         audio/webm; codecs="opus"
     Size:            8.74 MiB (9160971 Bytes)
     # download with: lux -f 251 ...

     [140]  -------------------
     Quality:         audio/mp4; codecs="mp4a.40.2"
     Size:            8.22 MiB (8614517 Bytes)
     # download with: lux -f 140 ...

     [250]  -------------------
     Quality:         audio/webm; codecs="opus"
     Size:            4.53 MiB (4748762 Bytes)
     # download with: lux -f 250 ...

     [249]  -------------------
     Quality:         audio/webm; codecs="opus"
     Size:            3.47 MiB (3637981 Bytes)
     # download with: lux -f 249 ...

As you can clearly see above, we now have multiple streams available, each providing a different video quality. Helpfully, it gives us the file size for each of these streams, so we can see that the highest-quality video is almost a hundred and thirty megabytes in size, whereas the video with the worst encoding is only three and a half megabytes.

(Remember that a megabit is one eighth of the size of a megabyte, because there are eight bits in a byte. Internet speed and download times are often measured in megabits, but files on our computer’s hard drive are generally given in megabytes. So we may need to do the conversion in our head, unless we have access to a calculator or online tool, if we’re trying to work out how long a certain file is likely to take to download with an Internet connection of a given speed.)

If we don’t have a lot of disk space available, we could make a huge saving by selecting one of the lower-quality streams. This will, of course, make the video less enjoyable to watch on large screens, since there will probably be more visual artifacts, so sometimes the tradeoff may not be worthwhile.

A young woman with her hand in her hair. The image is of low quality, showing the effect of visual artifacts.
This image of a female model contains clearly visible artifacts, because it was encoded as a .jpg file with a high level of compression, reducing its quality.

Soaring Over the Grand Canyon

As I discussed above, I am not going to use the Lux tool to download videos from sites that may prohibit this in their terms and conditions, but I have downloaded the freely available video of the Grand Canyon from the National Park Service. It’s as simple as running the following command:

lux -f default https://www.nps.gov/nps-audiovideo/legacy/grca/B6D01994-155D-451F-679C4406F71D1006/grca-desertviewrimcountrytiltup_480x270.mp4

This will create a new file in the current working directory to store the video: it will have the same filename as the original. If, however, you want to give it a custom filename or store it at another location on your file system, you can use the lower-case -o option to set a custom path and the upper-case -O option to set a custom filename. For example, you could download the video to the temporary directory with a simpler filename like so:

lux -f default -o /tmp -O the-grand-canyon https://www.nps.gov/nps-audiovideo/legacy/grca/B6D01994-155D-451F-679C4406F71D1006/grca-desertviewrimcountrytiltup_480x270.mp4

We don’t need to add the .mp4 file extension to our custom name when using the -O option, because Lux will append it automatically. If you added it anyway, the output filename would end up having two extensions (i.e. “the-grand-canyon.mp4.mp4”), which is clearly not what we want. Maybe future versions of Lux will correct for this, since it would be very easy to include a simple validation check, ensuring that no more than one of them is used.

Calling Lux From Go Code

Although this isn’t documented by the creators of the Lux tool, it is also possible to use their packages in your own Go code, if you want to download videos programmatically. The following example gets the same video of the Grand Canyon that we previously downloaded at the command line:

package main

import (
	"github.com/iawia002/lux/downloader"
	"github.com/iawia002/lux/extractors"
	"github.com/iawia002/lux/extractors/types"
)

const (
	videoURL   = "https://www.nps.gov/nps-audiovideo/legacy/grca/B6D01994-155D-451F-679C4406F71D1006/grca-desertviewrimcountrytiltup_480x270.mp4"
	outputName = "the-grand-canyon"
	outputPath = "/tmp"
)

func main() {
	data, err := extractors.Extract(videoURL, types.Options{})
	if err != nil {
		panic(err)
	}

	myDownloader := downloader.New(downloader.Options{
		OutputName: outputName,
		OutputPath: outputPath,
	})

	for _, item := range data {
		if item.Err != nil {
			panic(err)
		}

		if err = myDownloader.Download(item); err != nil {
			panic(err)
		}
	}
}

You could, of course, wrap this functionality within your own facade function, allowing you to call it with relevant arguments whenever you need to download a video. It is also worth looking at the original definitions of the types.Data, types.Options and downloader.Options structs, so you can see what other options are available to set.

Leave a Reply

Your email address will not be published. Required fields are marked *