Announcement

Collapse
No announcement yet.

BASH: Automatically Use File Name for file Out Put

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    BASH: Automatically Use File Name for file Out Put

    The thread title may not be the best wording, but I couldn't figure out a better way to word it so my apologies if you find this to be a poor thread title..moving on...

    Occasionally I need to convert the audio of problematic MKVs and remux them back in to MKV. I use ffmpeg like so:
    Code:
    ffmpeg -i *.mkv -vcodec copy -acodec ac3 -ab 256000 output.mkv
    This gets the job done but I either need to insert the target file name manually in the cli or I rename "output.mkv." Instead, is it possible to take the filename of the source mkv and simply append a 1 to the filename? So if *.mkv finds somevideo.mkv can I make it so the remux files would automaticly be named somevideo1.mkv?
    Last edited by Xplorer4x4; Sep 23, 2012, 06:55 PM.
    OS: Kubuntu 12.10/Windows 8
    CPU: Intel Core i7 2600K
    Motherboard: Gigabyte GA-Z77X-UD5H
    Memory: 2x4GB Corsair Dominator
    Graphics Card: MSI R7770
    Monitor: Dell 2208WFP
    Mouse: Mionix NAOS 5000
    PSU: Corsair 520HX
    Case: Thermaltake Mozart TX
    Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
    Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

    #2
    Simple solution is to create a script with the following:
    Code:
    #!/bin/bash
    ffmpeg -i "${1}" -vcodec copy -acodec ac3 -ab 256000 "${2}"
    you can then launch it with ./scriptname input_file_name.mkv output_file_name.mkv

    or for a more advanced approach:
    Code:
    #!/bin/bash
    input="${1}"
    
    if [ -z "${2}" ] ; then
        extension="${input##*.}"
        filename="${input%.*}"
        output="${filename}-1.${extension}"
    else
        output="${2}"
    fi
    
    ffmpeg -i "${input}" -vcodec copy -acodec ac3 -ab 256000 "${output}"
    and invoke it with./scriptname input_file.mkv and it will create the output as input_file-1.mkv or execute it with ./scriptname input.mkv output.mkv to create output.mkv (though I have not tested this script)

    You could use this with the find command to use this script on multiple files:
    Code:
    find -iname "*.mkv" -exec ./scriptname "{}" ";"
    which will execute the script for each file it finds with the .mkv extension (recursively).
    Last edited by james147; Sep 23, 2012, 07:49 PM.

    Comment


      #3
      you might want to investigate regexp (regular expressions), I know it is 100 percent possible to do what you want, but have no idea how. But it will involve regex

      Comment


        #4
        James, thanks! that works great. I was hopping to keep it simple to add to a service menu but in my own research I pretty much conclude it is not possible to do it strictly in a service menu, which often seems to be the case with my service menu needs so I need to figure a way to keep the servicemenu folder organized.

        Claydoh, thanks but I hate regex for the most part. php,bash,html even c++, sure no problem but I just never have been able to wrap my hear around regex.


        I am a bit confused though, when I use ffmpeg through the service menu, the bitrate of the video drops by 2, so say the bitrate is 5000, the output video is 4998. However If I run ffmpeg using the code from the op, the bitrate does not change at all. I am bit confused why the bitrate would change since both use vcodec copy
        Last edited by Xplorer4x4; Sep 24, 2012, 02:22 PM.
        OS: Kubuntu 12.10/Windows 8
        CPU: Intel Core i7 2600K
        Motherboard: Gigabyte GA-Z77X-UD5H
        Memory: 2x4GB Corsair Dominator
        Graphics Card: MSI R7770
        Monitor: Dell 2208WFP
        Mouse: Mionix NAOS 5000
        PSU: Corsair 520HX
        Case: Thermaltake Mozart TX
        Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
        Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

        Comment


          #5
          Two thoughts:

          1. What if, rather than renaming the target, you rename the source prior to the ffmpeg command then use the input name as the output name? Then you need only delete the old file once you've verified the new one - rather than going through a round of renaming the files you're saving.

          2. ffmpeg is being phased out in favor of avconv.

          The service menu causing the bitrate drop is really wierd. I'm going to have to test this on my system to see if I get the same results.

          Please Read Me

          Comment


            #6
            1. Not a bad idea but this is essentially the process I am used to and it would probably slow down my productivity, not that it matters that much since it is not like this is work related, as it would probably result in me transferring the wrong file to my "NAS" a lot of times. When transferring a 5+GB file at ~9MB/s I would rather not have to re-transfer often. I am sure other who find the thread might like this method more though if you want to share.

            2. Thanks I will look in to that.
            OS: Kubuntu 12.10/Windows 8
            CPU: Intel Core i7 2600K
            Motherboard: Gigabyte GA-Z77X-UD5H
            Memory: 2x4GB Corsair Dominator
            Graphics Card: MSI R7770
            Monitor: Dell 2208WFP
            Mouse: Mionix NAOS 5000
            PSU: Corsair 520HX
            Case: Thermaltake Mozart TX
            Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
            Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

            Comment


              #7
              Re. #1 I should have said "Have the script rename the original file". I was just thinking, since you're going to use a script, you might as well automate as much as possible.

              Please Read Me

              Comment


                #8
                I understood, guess I read it wrong. I just don't see the point in doing any renaming. Typically I just remux and move the new file to my NAS. The original file is just deleted and the copy on my NAS is typically deleted after watching. On a rare occasion I may decide to archive it back on one of my internal HDDs but only then do I bother with any renaming.

                Now I may not be thinking outside the box, so if I am missing how this would be beneficial in my case, I am all open for suggestions, but for my needs, it is adding a step I do not normally do anyways even if it is automated.
                OS: Kubuntu 12.10/Windows 8
                CPU: Intel Core i7 2600K
                Motherboard: Gigabyte GA-Z77X-UD5H
                Memory: 2x4GB Corsair Dominator
                Graphics Card: MSI R7770
                Monitor: Dell 2208WFP
                Mouse: Mionix NAOS 5000
                PSU: Corsair 520HX
                Case: Thermaltake Mozart TX
                Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
                Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

                Comment


                  #9
                  This one is even better (and there is no need for renaming anything since it automatically outputs filename.extension to filename-1.extension thus keeping the original intact).

                  Code:
                  #!/bin/bash
                  convert() {
                      input="${1}"
                      extension="${input##*.}"
                      filename="${input%.*}"
                      output="${filename}-1.${extension}"
                  
                  
                      if ffmpeg -i "${input}" -vcodec copy -acodec ac3 -ab 256000 "${output}"; then
                          kdialog --passivepopup "Completed ${output}" 60
                      else
                          kdialog --passivepopup "Failed ${output}" 60
                          return 1 # Change to exit 1 to stop the script on first failure
                      fi
                  }
                  
                  if [ -z "${1}" ] ; then
                      echo "Not enough arguments, exiting"
                      exit 1
                  fi
                  
                  for file in ${@} ; do
                      convert ${file}
                  done
                  You should be able to combine this with a service menu that contains the exec line:
                  exec=/path/to/script/scriptname %F

                  This should allow you to convert multiple files at once and tell you when it has finished each file

                  Again this is untested.

                  You can also add a
                  Code:
                  rm -f ${input}
                  after the success message to delete the input file if you never need it, but I would keep it just incase the convert fails.
                  Last edited by james147; Sep 27, 2012, 05:37 AM. Reason: Fixed errors in script

                  Comment


                    #10
                    Code:
                    #Exec=konsole --hold --workdir %f -e find  -maxdepth 1 -iname "*.mkv" -exec ~/.kde/share/kde4/services/ServiceMenus/ffmpeg.sh "{}" ";"
                    This is what I was using but your method does look much nicer, but I can't get it to work. When I click the command in the service menu, nothing happens. Not even the new file is silently produced in the working dir.
                    OS: Kubuntu 12.10/Windows 8
                    CPU: Intel Core i7 2600K
                    Motherboard: Gigabyte GA-Z77X-UD5H
                    Memory: 2x4GB Corsair Dominator
                    Graphics Card: MSI R7770
                    Monitor: Dell 2208WFP
                    Mouse: Mionix NAOS 5000
                    PSU: Corsair 520HX
                    Case: Thermaltake Mozart TX
                    Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
                    Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

                    Comment


                      #11
                      Does anything happen if you add "konsole --hold -e" before the command?

                      Comment


                        #12
                        Warning: Could not find '/home/xplorer4x4/.kde/share/kde4/services/ServiceMenus/ffmpeg2.sh', starting '/bin/bash' instead. Please check your profile settings.
                        The thing Is I am looking in the ServiceMenus folders and the script is there. :s

                        Update:
                        If I add konsole --hold -e sh /path/to.script.sh I get this:
                        /home/xplorer4x4/.kde/share/kde4/services/ServiceMenus/ffmpeg2.sh: 23: /home/xplorer4x4/.kde/share/kde4/services/ServiceMenus/ffmpeg2.sh: Syntax error: Unterminated quoted string
                        Going to look at line 23 and see what I find.

                        Update2:
                        Lines 23 is the last line that says done, so I tried done; but no luck.

                        Update 3:
                        Solved, on line 17 you had:
                        Code:
                        if [ -z "${1} ] ; then
                        You missed a closing quote:
                        Code:
                        if [ -z "${1}" ] ; then
                        So it works fine in konsole, and I tested the updated version in a service menu using Exec=/path/to/ffmpeg.sh %U and it is back to doing nothing at all. I am wondering if the script would need to be place in /usr/bin/ or atleast symlinked then called through the service menu as ffmpeg2.sh(Not I am actually using avconv now but for the sake of keeping it simple seems easier to follow the trend of using ffmpeg,
                        Last edited by Xplorer4x4; Sep 26, 2012, 04:17 PM.
                        OS: Kubuntu 12.10/Windows 8
                        CPU: Intel Core i7 2600K
                        Motherboard: Gigabyte GA-Z77X-UD5H
                        Memory: 2x4GB Corsair Dominator
                        Graphics Card: MSI R7770
                        Monitor: Dell 2208WFP
                        Mouse: Mionix NAOS 5000
                        PSU: Corsair 520HX
                        Case: Thermaltake Mozart TX
                        Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
                        Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

                        Comment


                          #13
                          I updated the script in comment #9 to fixs some errors (not just the missing ").

                          Is the script executable? It shouldn't matter where it is if you use the full path. Here is the service menu I used to test it

                          Code:
                          [Desktop Entry]
                          Actions=Convert;
                          Type=Service
                          ServiceTypes=KonqPopupMenu/Plugin
                          MimeType=all/all;
                          
                          
                          [Desktop Action Convert]
                          Name=Convert file
                          Type=Service
                          Exec=/home/james/test.sh %F
                          Note I change %U (list of URLs) to %F (list of files) but both should work for files, %F just stops it sending folders to the script.

                          Comment


                            #14
                            Thanks James, I updated the script and everything worked fine then. this is going to be so much more convenient and preferable to launching konsole.
                            OS: Kubuntu 12.10/Windows 8
                            CPU: Intel Core i7 2600K
                            Motherboard: Gigabyte GA-Z77X-UD5H
                            Memory: 2x4GB Corsair Dominator
                            Graphics Card: MSI R7770
                            Monitor: Dell 2208WFP
                            Mouse: Mionix NAOS 5000
                            PSU: Corsair 520HX
                            Case: Thermaltake Mozart TX
                            Cooling: Thermalright TRUE Black Ultra-120 eXtreme CPU Heatsink Rev C
                            Hard Drives: 1x180 GB Intel 330 SSD - 1xWD 1 TB Caviar Black - 1xWD 2 TB Caviar Green - 2xWD 3 TB Caviar Green

                            Comment

                            Working...
                            X