Sponsored Content
Top Forums Shell Programming and Scripting perl script chokes on dirs with spaces Post 302298089 by audiophile on Monday 16th of March 2009 04:54:02 PM
Old 03-16-2009
PHP perl script chokes on dirs with spaces

Basically, I have a perl script that calls enables one to resume where a video file left off (i.e. where the user stopped playback) that chokes on files that are located in a path that contains spaces.

To make the situation a little more complicated, the perl script gets help from a bash script that analyzes the video file in question and passes file-specific switches to mplayer.

Both scripts need to be in the same dir and you must run them from that dir!

Here is the usage:
Code:
$ ./mplayer-resumer-vdpau.pl /path/to/file.avi

(You can use any video format that mplayer can play, like mpg, mkv, etc.)

The problem occurs when the path to the video file contains a space. The perl script doesn't handle it and passes the incorrect options to the file.

Example: I go to play ‘Test.mkv' located in /media/D/New\ CD/

Code:
$ ./mplayer-resumer-vdpau.pl /media/D/New\ CD/Test.mkv 
File not found: '/media/D/New'
Failed to open /media/D/New.
File not found: '/media/D/New'
Failed to open /media/D/New.

Can someone have a look at the code and help me fix this? I just don't know that much about perl to be useful.

Code to mplayer-resumer-vdpau.pl
Code:
#!/usr/bin/perl

use Shell;
use strict;
use POSIX qw(floor);

# Written by Bob Igo from the MythTV Store at http://MythiC.TV
# Email: bob@stormlogic.com
#
# If you run into problems with this script, please send me email

# CHANGE LOG:
# 3/9/2009
# Modded Bob's wonderful resumer script to work with the vdpau
# options detector script by nickca of the linhes forums.
#
#  http://www.knoppmythwiki.org/index.php?page=HardwareAcceleratedVideo
#
# You need to have both this and the vdpau-detector script in the same
# dir for this to work properly.  Also, change your default mplayer
# options in mythfrontend to read simply: # mplayer-resumer-vdpau.pl %s
#
# To tweak the shell commands for mplayer, edit the vdpau-detector script.
# It has a small README inside it as comments
# ENJOY!

# 5/3/2006
# Added last time started checking.
# If this script is restarted within $tdiff (default 5 seconds)
# then it will delete the file used to keep track of the videos
# resume position.

# PURPOSE:
# --------------------------
# This is a wrapper script to prove the concept of having MythTV
# resume playback of previously-stopped video where you left off.
# It's likely that a good solution will look different than this
# initial code.

# RATIONALE:
# --------------------------
# Watching 90% of a video and stopping causes you to return to the
# beginning again the next time you watch it.  Remembering where
# you were in the video and resuming at that position is a much nicer
# behavior for the user.
#
# By default, mplayer spits out timecode information that tells you
# where you are in the video, to the tenth of a second.  Mplayer also
# supports a seek feature on the command-line.  We can make use of these
# features to write an mplayer wrapper that will remember the last
# position in a video file and resume to it on playback.

# PARAMETERS:
# --------------------------
# see print_usage() below

# FILES:
# --------------------------
# $infile, the video to play
# $resumefile, the video's resume file (see get_resume_filename() below)

# KNOWN ISSUES:
# --------------------------
# Mplayer misreports the timecodes on .nuv MPEG-2 files.  Currently, anything
# captured via an HDTV tuner card and put into your /myth/video directory
# will fail with this resumer.
#
# Current theories include the timecode having to do with the show's broadcast
# time, recording time, or perhaps its upload time to the station that
# broadcast it.

# DESIGN LIMITATION:
# -------------------------
# If the video file to be played is on a read-only filesystem, or otherwise
# lives in a location that cannot be written to, resume will fail.  This is
# because the current implementation uses a file parallel to the video file
# to store the timecode.
#

my $infile;
my $resumefile;
my $mplayer_parameters;
my $fudge_factor=2; # number of additional seconds to skip back before playback
my $tnow;    # Time now.
my $tprev;   # Time the prog was last started. 
             # Returned from the modification time of the xx.resume file.
my $tdiff=5; # How many seconds before we should start from 
             # the beginning of the movie
#DEBUG
#open(DEBUG,">/tmp/debug") || die "unable to open debug file";

sub init () {
    $tnow = time();
    $infile = @ARGV[$#ARGV];

    $resumefile = &get_resume_filename($infile);
    # This returns the 9th element of the 13 element array 
    # created by the stat function.
    $tprev = (stat ($resumefile))[9]; 
    # if this file is restarted in less than 5 seconds then 
    # remove the .resume file
    if ( ($tnow - $tprev) < $tdiff ) {
        unlink($resumefile);
    }

    $mplayer_parameters = join(' ',@ARGV[0..$#ARGV-1]);
}

&init();
&save_time_offset(&mplayer($mplayer_parameters,$infile), $resumefile);

#close(DEBUG);

# For $pathname, return $path.$filename.resume
sub get_resume_filename () {
    my($pathname)=@_;
    
    my $idx = rindex($pathname,"/");

    if ($idx == -1) { # There was no "/" in $pathname
    return ".".$pathname.".resume";
    } else {
    # Now we need to split out the path from the filename.
    my $path = substr($pathname,0,$idx+1);
    my $filename = substr($pathname,$idx+1);
    return "$path.$filename.resume";
    }
}

# Calls mplayer and returns the last known video position
sub mplayer () {
    my($parameters,$infile)=@_;
    my $seconds=0;
    my $timecode=&get_time_offset($infile);
    my $mplayeropts=`./vdpau-detector $infile`; chomp $mplayeropts;
    my @lines = split "\n", $mplayeropts;
    my $last_line = pop(@lines);
    my $command = "mplayer $last_line $parameters -ss $timecode \"$infile\" 2>&1 2>/dev/null |";

    open(SHELL, $command);
    # The kind of line we care about looks like this example:
    # A:1215.2 V:1215.2 A-V:  0.006 ct:  0.210 207/201 13%  0%  1.9% 0 0 68%
    # But all we care to look at is the first number.
    
    while (<SHELL>) {
    #print DEBUG $_;
    if (m/A: *[0-9]+\.[0-9]/) { # See if this line has timecodes on it
        my $last_timecode_line = &extract_last_timecode_line($_);
        if ($last_timecode_line =~ m/ *([0-9]+\.[0-9]) V/) {
        $seconds=$1;
        }
    }
    }
    close(SHELL);

    return $seconds;

    sub extract_last_timecode_line () {
    my ($line)=@_;
    my @lines=split('A:',$line);
    return @lines[$#lines-1];
    }
}

# Save the last known video position
sub save_time_offset () {
    my($seconds, $resumefile)=@_;

    open(RESUMEFILE, ">$resumefile") || die "Unable to open $resumefile for writing";
    print RESUMEFILE "$seconds";
    close(RESUMEFILE);
}

# returns the number of seconds corresponding to the last known video position,
# in hh:mm:ss format, compatible with the "-ss" parameter to mplayer
sub get_time_offset () {
    my($videofile)=@_;
    my($resumefile) = &get_resume_filename($videofile);
    my $seconds=0;
    my $timecode;

    open(RESUMEFILE, "<$resumefile") || return "00:00:00";
    while(<RESUMEFILE>) {
    $seconds=$_;
    }
    close(RESUMEFILE);

    my $hours = floor($seconds/3600);
    $seconds = $seconds - $hours*3600;

    my $minutes = floor($seconds/60);
    $seconds = int($seconds - $minutes*60) - $fudge_factor;

    $timecode = sprintf "%02d:%02d:%02d",$hours,$minutes,$seconds;
#    print "TIMECODE: $timecode\n";
    return $timecode;
}

sub print_usage () {
    print "USAGE:\n";
    print "\t",$ARGV[0], "[mplayer parameters] video_file\n";
    print "\t","e.g. ",$ARGV[0], "-fs -zoom my.mpg\n";
    print "\t","Version 3/9/2009\n";
}

Code to vdpau-detector
Code:
#!/bin/bash

# This script written by nickca on the linhes forums
# Original page http://www.knoppmythwiki.org/index.php?page=HardwareAcceleratedVideo
#
# It's modded to allow vdpau switches commands to pass to a modded version of Bob Igo's
# mplayer-resumer.pl wrapper for mplayer
#
# User can customize commandline for mplayer by editing the appropriate sections below
# They include BASIC_OPTS, NOHD_OPTS, and LOW_OPTS

IAM=$0
FILE=$1

#if no input display usage
if [[ -z "$FILE" ]]; then
        echo usage: $0 /path/to/file
        exit
fi

MPLAYER="/usr/bin/mplayer"

# For a complete list of options, see the mplayer DOCS
# http://www.mplayerhq.hu/DOCS/man/en/mplayer.1.html
#

# Options for all videos: fullscreen, zoom, and use software eq
BASIC_OPTS="-fs -zoom"

# Options for non-HD videos: force aspect to 16x10 (to ensure video fills TV screen)
# You'll need to modify the ratio if your res differs
# Example: 1920x1080 = 1.778 = 16:9
# Example: 1680x1050 = 1.600 = 16:10
# Example: 1280x720 = 1.778 = 16:9

NOHD_OPTS="-aspect 16:10"

# Options for normal and lowres videos: use XV forcing 16x10
LOW_OPTS="-aspect 16:10 -vo xv"

VWIDTH=$($MPLAYER -identify -vo vdpau -frames 0 "$FILE" | grep ID_VIDEO_WIDTH | cut -c 16-25)
VCODEC=$($MPLAYER -identify -vo vdpau -frames 0 "$FILE" | grep ID_VIDEO_CODEC | cut -c 16-25)

# all following echo commands can be uncommented for debug info
#echo .
#echo " DEBUG info: video codec: $VCODEC"
#echo " DEBUG info: video width: $VWIDTH"
#echo " Debug info: 


# Test for codec, if it's supported by VDPAU, set options to use it. Then, check if the video is in HD,
# and if it's not, set non-HD options.
case $VCODEC in
ffh264) 
        #echo -e "Playing h.264 file $FILE:\n"
        MPLAYEROPTS="$BASIC_OPTS -vo vdpau -vc ffh264vdpau"
        if [ $VWIDTH -lt 1280 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$MPLAYEROPTS $NOHD_OPTS"
        fi
        if [ $VWIDTH -lt 700 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$BASIC_OPTS $LOW_OPTS"
        fi
        ;;
ffmpeg2)
        #echo -e "Playing MPEG2 file $FILE:\n"
        MPLAYEROPTS="$BASIC_OPTS -vo vdpau -vc ffmpeg12vdpau"
        if [ $VWIDTH -lt 1280 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$MPLAYEROPTS $NOHD_OPTS"
        fi
        if [ $VWIDTH -lt 700 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$BASIC_OPTS $LOW_OPTS"
        fi
        ;;
ffwmv3)
        #echo -e "Playing WMV3 file $FILE:\n"
        MPLAYEROPTS="$BASIC_OPTS -vo vdpau -vc ffwmv3vdpau"
        if [ $VWIDTH -lt 1280 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$MPLAYEROPTS $NOHD_OPTS"
        fi
        if [ $VWIDTH -lt 700 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$BASIC_OPTS $LOW_OPTS"
        fi
        ;;
# VC-1 is largely unsupported by nvidia - uncomment this section if you're sure your card supports it.
ffvc1)
        #echo -e "Playing VC-1 file $FILE:\n"
        MPLAYEROPTS="$BASIC_OPTS -vo vdpau -vc ffvc1vdpau"
        if [ $VWIDTH -lt 1280 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$MPLAYEROPTS $NOHD_OPTS"
        fi
        if [ $VWIDTH -lt 700 ] && [ $VWIDTH != 0 ]; then
                MPLAYEROPTS="$BASIC_OPTS $LOW_OPTS"
        fi
        ;;
*)
        #echo -e "Playing normal file $FILE:\n"
        # Use XV and yadif filter with 'normal' (DiVX, XViD, old WMV, etc.) files, and force 16:9
        # -vf filters only seem to work with XV, or at least they don't work w/VDPAU
        MPLAYEROPTS="$BASIC_OPTS $LOW_OPTS"
        ;;
esac

echo $MPLAYEROPTS

 

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

shell script to create dirs

hi, I would like to know of a shell script to create the following A script which will take in two parameters i.e. name of file and SID and create directories named /opt/oracle/admin/$SID/{bdump,cdump,udump}. Then edit the init file and change the three lines that look like this. ... (2 Replies)
Discussion started by: sjajimi
2 Replies

2. Shell Programming and Scripting

script find files in two dirs HELP

I have a directory which is /home/mark/files/ , inside this particular I have a bunch of filles (see examples below) TST_SHU_00014460_20090302.txt TST_SHU_00016047_20090302.txt TST_SHU_00007838_20090303.txt TST_SHU_00056485_20090303.txt TST_SHU_00014460_20090303.txt... (2 Replies)
Discussion started by: fierusbentus
2 Replies

3. Shell Programming and Scripting

Removing leading and trailing spaces only in PERL

Hi All, I have a file with the following contents with multiple lines 172445957| 000005911|8| 400 Peninsula Ave.#1551 | And,K |935172445957|000005911 607573888 |000098536 | 2|Ane, B |J |Ane |1868 |19861206|20090106|20071001 I want to trim the "leading and trailing spaces only" from... (2 Replies)
Discussion started by: kumar04
2 Replies

4. UNIX for Advanced & Expert Users

script to recursively change permissions on file and dirs differently?

Hi there, I need to change all files/dirs 1. all files with 744 2. all dirs with 755 is there a script for that ? thanks, thegunman (13 Replies)
Discussion started by: TheGunMan
13 Replies

5. Shell Programming and Scripting

Not correct processing of “\ “ in names of dirs inside shell script (tar command - system backup scr

Hello, Recently, I've started with shell scripting, and decided to write a script for my system backup using tar. When I was dealing with tar execution inside shell script I found this, inside shell we have the following code: tar $TAR_PARAMS $ARCHIVE_FILE $EXCLUDE $BACKUP_STARTwith... (6 Replies)
Discussion started by: ilnar
6 Replies

6. UNIX for Dummies Questions & Answers

**HELP** how to do a listing of dirs and all sub dirs only

I am trying to get a listing of ALL directories only under /export (as an example). I can get all the dirs directly under /export but I need any sub dirs under those dirs. I've looked (here and google) but can not find anything that works (4 Replies)
Discussion started by: bbraml
4 Replies

7. Shell Programming and Scripting

PERL : Remove spaces in a variable

I have a variable I want to remove the spaces in between. The output should be How can this be done Any help will be appreciated. Thanks in advance (1 Reply)
Discussion started by: irudayaraj
1 Replies

8. Shell Programming and Scripting

Perl : Arrays : where are these spaces coming from

Example data The sub and array in question sub parse_status { my $status_info = shift; my @info; push @info,"$1\n" if $status_info =~ /(System State : +)/; push @info, "System_Uptime : $1\n" if $status_info =~ /Uptime:.+?up (.+?), load/; push @info, "$1\n" if $status_info =~... (2 Replies)
Discussion started by: popeye
2 Replies

9. Shell Programming and Scripting

Dealing with filename spaces in Perl

The following command to replace text in place in multiple files in a directory is tripping up on filename spaces (Windows environment). I really don't know Perl. find '\\server\directory' | xargs perl -pi -e 's/textA/textB/g'Mike (2 Replies)
Discussion started by: Michael Stora
2 Replies

10. Shell Programming and Scripting

Iterate over `dirs` in a bash script

I would like to iterate over `dirs`in a script, but the script will never show more than one (current) folder #! /bin/bash for i in `dirs` do echo ${i} done echo ++++++++++++++++++ for i in $( dirs -p ) do echo ${i} done echo ------------------ dirscontent=`dirs` echo... (5 Replies)
Discussion started by: alexanderb
5 Replies
All times are GMT -4. The time now is 11:11 PM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy