2

I'm using my ssh server to record videos and I'd like to be able to watch them (on a PC using Windows 7 or 8) during the recording. I can of course transfer the file when I'm done and watch it, but I want to watch it during the recording, that can last 2 hours.

I don't want to use a VLC server because it encodes the video and my SSH Server is on an Odroid C1 (not powerful enough for that I think), and I would loose some quality.

I saw here some ideas VLC: Can I stream over SSH? but that's not enough.

I've thought about 2 angles here:

  • Finding a way to download the file "indefinitely": meaning that as long as the file is getting bigger, the download would continue. But I don't know if that's possible, I've tried WinSCP but the download ends even thought the file is constantly updating.
  • Streaming the file with something like this in VLC "sftp:///" but I don't know how to configure the connection with VLC (my SSH connection is not on port 22 and I use public/private keys).

Does someone have any ideas?

3
  • What is the input? A live source? How are you recording the video exactly? What format are you recording to?
    – slhck
    Commented Mar 17, 2015 at 14:14
  • I've written a java program that record a live source into a file (with a "simple" FileOutputStream). The file is an mpeg file, and is "growing" until the recording is over.
    – Syl
    Commented Mar 17, 2015 at 14:21
  • I tried several SFTP clients, but in every case I have to download the file first before opening it. I hoped Swish would help but even if we can have a link like : sftp://user@server:port/path/file.mpeg, the file is downloaded when you click on it, and the address doesn't work with VLC.
    – Syl
    Commented Mar 19, 2015 at 10:59

1 Answer 1

3

Since all my attempts to stream directly with VLC with a "sftp://" link failed, I managed to write a little java program that would do exactly what I needed by downloading the file and by always checking if the size of the remote file has changed to resume the download if needed.

The key here is that piece of code:

    sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.OVERWRITE, 0);
    long localSize;
    Thread.sleep(1000);
    while(sftpChannel.lstat(remotePath).getSize() > (localSize = new File(localPath).length())){
        sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.RESUME, localSize);
        Thread.sleep(timeToWaitBeforeUpdatingFile);

    }
    System.out.println("The download is finished.");

I'm also posting the whole code for the program if someone is interested:

package streamer;

import java.io.Console;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;
import java.util.Vector;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

public class Streamer {
    public static void main(String[] args) throws InterruptedException, IOException {
        JSch jsch = new JSch();

        if(args.length != 7){
            System.out.println("Incorrect parameters:");
            System.out.println("Streamer user host port privateKeyPath remotePath localPath vlcPath");
            System.exit(-1);
        }

        String user = args[0];
        String host = args[1];
        int port = -1;
        try {
            port = Integer.parseInt(args[2]);
        } catch (NumberFormatException e3) {
            System.out.println("Port must be an integer");
            System.exit(-1);
        }
        String privateKeyPath = args[3];

        String remotePath = args[4];
        String localPath = args[5];
        String vlcPath = args[6];

        int timeToWaitBeforeUpdatingFile = 5000;
        String password = "";

        Console console = System.console();
        if (console == null) {
            System.out.println("Couldn't get Console instance");
            //password = "";
            System.exit(-1);
        }else{
            char passwordArray[] = console.readPassword("Enter your password: ");
            password = new String(passwordArray);
            Arrays.fill(passwordArray, ' ');
        }

        try {
            jsch.addIdentity(privateKeyPath, password);
        } catch (JSchException e) {
            System.out.println(e.getMessage());
            System.out.println("Invalid private key file");
            System.exit(-1);
        }

        Session session;
        try {
            session = jsch.getSession(user, host, port);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            System.out.println("Establishing connection...");
            session.connect();
            System.out.println("Connection established.");
            System.out.println("Creating SFTP Channel...");
            ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
            sftpChannel.connect();
            System.out.println("SFTP Channel created.");

            try {
                @SuppressWarnings("unchecked")
                Vector<ChannelSftp.LsEntry> recordings = sftpChannel.ls(remotePath + "*.mpeg");
                if(recordings.isEmpty()){
                    System.out.println("There are no recordings to watch.");
                    System.exit(0);
                }
                int choice = 1;
                System.out.println("Chose the recording to watch:");
                for (ChannelSftp.LsEntry e : recordings){
                    System.out.println("[" + choice++ + "] " + e.getFilename());
                }
                Scanner sc = new Scanner(System.in);
                try {
                    String fileName = recordings.get(sc.nextInt() - 1).getFilename();
                    remotePath += fileName;
                    localPath += fileName;
                } catch (InputMismatchException e) {
                    System.out.println("Incorrect choice");
                    System.exit(-1);
                }
                System.out.println("You chose : " + remotePath);
                sc.close();
            } catch (SftpException e2) {
                System.out.println("Error during 'ls': the remote path might be wrong:");
                System.out.println(e2.getMessage());
                System.exit(-1);
            }

            OutputStream outstream = null;
            try {
                outstream = new FileOutputStream(new File(localPath));
            } catch (FileNotFoundException e) {
                System.out.println("The creation of the file" + localPath + " failed. Local path is incorrect or writing permission is denied.");
                System.exit(-1);
            }

            try {
                SftpProgressMonitor monitor = null;
                System.out.println("The download has started.");
                System.out.println("Opening the file in VLC...");
                try {
                    Runtime.getRuntime().exec(vlcPath + " " + localPath);
                } catch (Exception ex) {
                    System.out.println("The file couldn't be opened in VLC");
                    System.out.println("Check your VLC path.");
                    System.out.println(ex);
                }
                sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.OVERWRITE, 0);
                long localSize;
                Thread.sleep(1000);
                while(sftpChannel.lstat(remotePath).getSize() > (localSize = new File(localPath).length())){
                    sftpChannel.get(remotePath, outstream, monitor, ChannelSftp.RESUME, localSize);
                    Thread.sleep(timeToWaitBeforeUpdatingFile);

                }
                System.out.println("The download is finished.");
                outstream.close();
                System.exit(0);
            } catch (SftpException e1) {
                System.out.println("Error during the download:");
                System.out.println(e1.getMessage());
                System.exit(-1);
            }
        } catch (JSchException e) {
            System.out.println("Connection has failed (check the user, host, port...)");
            System.exit(-1);
        }
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .