Repository: streamlink/streamlink

Issue:
Add an option to disable the download progress log message
### Checklist

- [ ] This is a bug report.
- [x] This is a feature request.
- [ ] This is a plugin (improvement) request.
- [x] I have read the contribution guidelines.

### Description

Apart from regular console use, I also run Streamlink from Java (through a Java Process) and redirect the system output & error streams to Java. If I tell Streamlink to use a player, all is fine. However, if I tell Streamlink to save the file, it stops writing to the file after less than 1 minute. It appears to still be capturing as there are no new log messages to indicate an error but the file doesn't get any bigger.

After some investigating, it turns out to be the "[download] ??? Written ???" log message that clears the current line in order to print the new value that is causing the problem (the print_inplace function in progress.py). That log message isn't printed in Java which was a clue to the problem.

I've tried the none loglevel option but the download progress log message still appears. My only option ATM without modifying the Streamlink code myself is to turn the loglevel up to debug level causing no line clearing, just a whole lot of logspam, BUT a successful recording.

TLDR;
When I specify -Q option for quiet logging, can it NOT print the download progress as well please.
Or maybe an extra CLI argument to disable the download progress message altogether (or disable current line clearing and just write the new value on a new line). Ideally, I'd still like to get the error/warning/info log messages and just disable the constantly updating download progress.

### Comments, screenshots, etc.

Thanks to all the contributors for this awesome software.


Discussion:
I think the best thing here would be to only show that progress counter when there is a valid terminal to write to (can also remove it when using -q). Then you can set the log level to warning and still get those messages.
Same problem with python

Resolving patch:
diff --git a/src/streamlink_cli/main.py b/src/streamlink_cli/main.py
--- a/src/streamlink_cli/main.py
+++ b/src/streamlink_cli/main.py
@@ -57,10 +57,14 @@ def check_file_output(filename, force):
     log.debug("Checking file output")
 
     if os.path.isfile(filename) and not force:
-        answer = console.ask("File {0} already exists! Overwrite it? [y/N] ",
-                             filename)
+        if sys.stdin.isatty():
+            answer = console.ask("File {0} already exists! Overwrite it? [y/N] ",
+                                 filename)
 
-        if answer.lower() != "y":
+            if answer.lower() != "y":
+                sys.exit()
+        else:
+            log.error("File {0} already exists, use --force to overwrite it.".format(filename))
             sys.exit()
 
     return FileOutput(filename)
@@ -322,7 +326,7 @@ def read_stream(stream, output, prebuffer, chunk_size=8192):
     is_player = isinstance(output, PlayerOutput)
     is_http = isinstance(output, HTTPServer)
     is_fifo = is_player and output.namedpipe
-    show_progress = isinstance(output, FileOutput) and output.fd is not stdout
+    show_progress = isinstance(output, FileOutput) and output.fd is not stdout and sys.stdout.isatty()
 
     stream_iterator = chain(
         [prebuffer],


Test patch:
diff --git a/tests/test_cli_main.py b/tests/test_cli_main.py
--- a/tests/test_cli_main.py
+++ b/tests/test_cli_main.py
@@ -18,12 +18,25 @@ def test_check_file_output_exists(self):
         tmpfile = tempfile.NamedTemporaryFile()
         try:
             streamlink_cli.main.console = console = Mock()
+            streamlink_cli.main.sys.stdin = stdin = Mock()
+            stdin.isatty.return_value = True
             console.ask.return_value = "y"
             self.assertTrue(os.path.exists(tmpfile.name))
             self.assertIsInstance(check_file_output(tmpfile.name, False), FileOutput)
         finally:
             tmpfile.close()
 
+    def test_check_file_output_exists_notty(self):
+        tmpfile = tempfile.NamedTemporaryFile()
+        try:
+            streamlink_cli.main.console = console = Mock()
+            streamlink_cli.main.sys.stdin = stdin = Mock()
+            stdin.isatty.return_value = False
+            self.assertTrue(os.path.exists(tmpfile.name))
+            self.assertRaises(SystemExit, check_file_output, tmpfile.name, False)
+        finally:
+            tmpfile.close()
+
     def test_check_file_output_exists_force(self):
         tmpfile = tempfile.NamedTemporaryFile()
         try: