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?
Answer
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 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);
}
}
}
No comments:
Post a Comment