title: Adding subtitles to video with moviepy requiring encoding
body: <p>I have a srt file named <code>subtitles.srt</code> that is non-English, and I followed the instructions of the documentation and source code of the moviepy package (<a href="https://moviepy.readthedocs.io/en/latest/_modules/moviepy/video/tools/subtitles.html" rel="nofollow noreferrer">https://moviepy.readthedocs.io/en/latest/_modules/moviepy/video/tools/subtitles.html</a>):</p>
  <pre><code>from moviepy.video.tools.subtitles import SubtitlesClip
  from moviepy.video.io.VideoFileClip import VideoFileClip
  generator = lambda txt: TextClip(txt, font='Georgia-Regular', fontsize=24, color='white')
  sub = SubtitlesClip(&quot;subtitles.srt&quot;, generator, encoding='utf-8')
  </code></pre>
  <p>And this gives the error <code>TypeError: __init__() got an unexpected keyword argument 'encoding'</code>.</p>
  <p>In the source code, the class <code>SubtitlesClip</code> does have a keyword argument <code>encoding</code>. Does that mean the version of the source code is outdated or something? And what can I do about this? I even attempted to copy the source code for <code>moviepy.video.tools.subtitles</code> with the <code>encoding</code> keyword argument directly to my code, yet it led to more errors like at the line:</p>
  <pre><code>from moviepy.decorators import convert_path_to_string
  </code></pre>
  <p>it failed to import the decorator <code>convert_path_to_string</code>.</p>
  <p>The source code does not seem to agree with what I have installed. Anyway to fix it? If not, are there any good alternatives of Python libraries for inserting subtitles or video editing in general?</p>
  <p>Edit: My current solution is to create a child class of <code>SubtitlesClip</code> and override the constructor of the parent class:</p>
  <pre><code>from moviepy.video.tools.subtitles import SubtitlesClip
  from moviepy.video.VideoClip import TextClip, VideoClip
  from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip
  import re
  
  
  
  from moviepy.tools import cvsecs
  
  def file_to_subtitles_with_encoding(filename):
      &quot;&quot;&quot; Converts a srt file into subtitles.
  
      The returned list is of the form ``[((ta,tb),'some text'),...]``
      and can be fed to SubtitlesClip.
  
      Only works for '.srt' format for the moment.
      &quot;&quot;&quot;
      times_texts = []
      current_times = None
      current_text = &quot;&quot;
      with open(filename,'r',encoding='utf-8') as f:
          for line in f:
              times = re.findall(&quot;([0-9]*:[0-9]*:[0-9]*,[0-9]*)&quot;, line)
              if times:
                  current_times = [cvsecs(t) for t in times]
              elif line.strip() == '':
                  times_texts.append((current_times, current_text.strip('\n')))
                  current_times, current_text = None, &quot;&quot;
              elif current_times:
                  current_text += line
      return times_texts
  
  
  class SubtitlesClipUTF8(SubtitlesClip):
      def __init__(self, subtitles, make_textclip=None):
          
          VideoClip.__init__(self, has_constant_size=False)
  
          if isinstance(subtitles, str):
              subtitles = file_to_subtitles_with_encoding(subtitles)
  
          #subtitles = [(map(cvsecs, tt),txt) for tt, txt in subtitles]
          self.subtitles = subtitles
          self.textclips = dict()
  
          if make_textclip is None:
              make_textclip = lambda txt: TextClip(txt, font='Georgia-Bold',
                                          fontsize=24, color='white',
                                          stroke_color='black', stroke_width=0.5)
  
          self.make_textclip = make_textclip
          self.start=0
          self.duration = max([tb for ((ta,tb), txt) in self.subtitles])
          self.end=self.duration
          
          def add_textclip_if_none(t):
              &quot;&quot;&quot; Will generate a textclip if it hasn't been generated asked
              to generate it yet. If there is no subtitle to show at t, return
              false. &quot;&quot;&quot;
              sub =[((ta,tb),txt) for ((ta,tb),txt) in self.textclips.keys()
                     if (ta&lt;=t&lt;tb)]
              if not sub:
                  sub = [((ta,tb),txt) for ((ta,tb),txt) in self.subtitles if
                         (ta&lt;=t&lt;tb)]
                  if not sub:
                      return False
              sub = sub[0]
              if sub not in self.textclips.keys():
                  self.textclips[sub] = self.make_textclip(sub[1])
  
              return sub
  
          def make_frame(t):
              sub = add_textclip_if_none(t)
              return (self.textclips[sub].get_frame(t) if sub
                      else np.array([[[0,0,0]]]))
  
          def make_mask_frame(t):
              sub = add_textclip_if_none(t)
              return (self.textclips[sub].mask.get_frame(t) if sub
                      else np.array([[0]]))
          
          self.make_frame = make_frame
          hasmask = bool(self.make_textclip('T').mask)
          self.mask = VideoClip(make_mask_frame, ismask=True) if hasmask else None
  </code></pre>
  <p>I actually only changed two lines, but I have to create a new class and redefine the whole thing, so I doubt whether it's really necessary. Any better solution than this?</p>