code: def to_file(self, path):
          
          xmp_path = path + '.xmp'
          # remove any existing XMP file
          if os.path.exists(xmp_path):
              os.unlink(xmp_path)
          # attempt to open image/video file for metadata
          md_path = path
          md = GExiv2.Metadata()
          try:
              md.open_path(md_path)
          except GLib.GError:
              # file type does not support metadata so use XMP sidecar
              md_path = xmp_path
              # create empty XMP file
              with open(md_path, 'w') as of:
                  of.write('''<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
  <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description rdf:about=""
      xmlns:xmp="http://ns.adobe.com/xap/1.0/"
     xmp:CreatorTool=""/>
   </rdf:RDF>
  </x:xmpmeta>
  <?xpacket end="w"?>''')
              md = GExiv2.Metadata()
              md.open_path(md_path)
          # add our namespace
          md.register_xmp_namespace(
              'https://github.com/jim-easterbrook/pyctools', 'pyctools')
          # copy metadata
          for tag, value in self.data.items():
              if md.get_tag_type(tag) in ('XmpBag', 'XmpSeq'):
                  md.set_tag_multiple(tag, value)
              else:
                  md.set_tag_string(tag, value)
          if self.comment is not None:
              md.set_comment(self.comment)
          # save file
          md.save_file(md_path)
docs: Write metadata to an image, video or XMP sidecar file.
  
          :param str path: The image/video file path name.